LOJ4222 「IOI2024」马赛克上色 题解

news/2024/9/19 7:27:33/文章来源:https://www.cnblogs.com/peiwenjun/p/18409212

题目描述

给定长为 \(n\) 、下标从零开始的 \(01\) 序列 \(x,y\) ,保证 \(x_0=y_0\)

\(col_{0,j}=x_j,col_{i,0}=y_i\) ,对 \(\forall 1\le i\lt n,1\le j\lt n\)\(col_{i,j}=[col_{i-1,j}=0\and col_{i,j-1}=0]\)

\(q\) 次询问,给定 \(u,d,l,r\) ,求 \(\sum_{i=u}^d\sum_{j=l}^rcol_{i,j}\)

数据范围

  • \(1\le n,q\le 2\cdot 10^5\)
  • \(0\le u\lt d\lt n,0\le l\lt r\lt n\)

时间限制 \(\texttt{1s}\) ,空间限制 \(\texttt{2048MB}\)

分析

先分析 \(col\) 矩阵的性质。

先暴力求出所有满足 \(\min(i,j)\le 2\) 的位置(即前 \(3\)\(3\) 列)的值,容易发现:

  • 对于数列 \(col_{n-1,1}\cdots,col_{1,1},col_{1,n-1}\) ,不会有连续两个 \(1\)

证明:

显然。

  • 对于数列 \(col_{n-1,2},\cdots,col_{2,2},\cdots,col_{2,n-1}\) ,不会有连续两个 \(1\) ,也不会有连续 \(3\)\(0\)

证明:

前半部分显然,下面仅考虑后半部分。

\(col_{i+1,2}=col_{i,2}=col_{i-1,2}=0\) ,则 \(col_{i+1,1}=col_{i,1}=1\) ,矛盾。

\(col_{3,2}=col_{2,2}=col_{2,3}=0\) ,则 \(col_{3,1}=col_{1,3}=1\) ,且 \(col_{2,1}\)\(col_{1,2}\) 至少一个为 \(1\) ,矛盾。

\(col_{2,j-1}=col_{2,j}=col_{2,j+1}=0\) ,则 \(col_{1,j}=col_{1,j+1}=1\) ,矛盾。

综上即可得证。

再考虑 \(i\ge 2,j\ge 2\) 时,每个 \(1\) "管辖" 的范围。

它所在斜线一定为 \(1\) ,并且相邻两条斜线一定为 \(0\) ,如下图所示:

image

通过上述性质我们可以按照斜线不重不漏确定整个矩阵,这是因为两条相邻的斜线 \(1\) 之间只能间隔 \(1\)\(2\) 条斜线 \(0\)


对询问做二维差分,单独处理前 \(2\)\(2\) 列,转化为求 \(\sum_{i=2}^a\sum_{j=2}^b col_{i,j}\)

为方便起见,记 \(m=n-2,a\gets a-1,b\gets b-1\) ,令矩阵下标从 \(1\) 开始。

\(o_1,\cdots,o_{2m-1}\) 表示每条斜线的数值,对斜线出发点和穿过询问矩形的边界分类讨论:

  • 出发点在左边界,穿过矩形下边界:贡献 \(\sum(a+i-m)\cdot o_i\)
  • 出发点在左边界,穿过矩形右边界:贡献 \(\sum b\cdot o_i\)
  • 出发点在上边界,穿过矩形下边界:贡献 \(\sum a\cdot o_i\)
  • 出发点在上边界,穿过矩形右边界:贡献 \(\sum(b+m-i)\cdot o_i\)

预处理 \(\sum o_i\)\(\sum i\cdot o_i\) 即可做到 \(\mathcal O(1)\) 回答,注意经过左上角和右下角的斜线不要算重。

时间复杂度 \(\mathcal O(n+q)\)

#include<bits/stdc++.h>
#include"mosaic.h"
#define ll long long
#define vi vector<int>
using namespace std;
const int maxn=2e5+5;
int m;
int o[2*maxn],s1[maxn],s2[maxn],s3[maxn],s4[maxn];
ll t1[2*maxn],t2[2*maxn];
vi col[maxn];
ll get(int l,int r,int x,int y)
{///\sum_{i=l}^r(x+y*i)*o[i]return l<=r?x*(t1[r]-t1[l-1])+y*(t2[r]-t2[l-1]):0;
}
ll calc(int a,int b)
{if(min(a,b)<0) return 0;ll res=0;for(int i=0;i<=1;i++)for(int j=0;j<=1;j++)if(i<=a&&j<=b) res+=col[i][j];if(a>=0) res+=s1[b];if(a>=1) res+=s2[b];if(b>=0) res+=s3[a];if(b>=1) res+=s4[a];if(--a>=1&&--b>=1){res+=get(m+1-a,min(m,b-a+m),a-m,1);res+=get(b-a+m+1,m,b,0);res+=get(m+1,b-a+m,a,0);res+=get(max(m+1,b-a+m+1),m+b-1,b+m,-1);}return res;
}
vector<ll> mosaic(vi x,vi y,vi u,vi d,vi l,vi r)
{int n=x.size(),q=u.size();for(int i=0;i<n;i++){col[i].resize(i<3?n:3);for(int j=0;j<col[i].size();j++){if(!i) col[i][j]=x[j];else if(!j) col[i][j]=y[i];else col[i][j]=!col[i-1][j]&!col[i][j-1];}}for(int i=2;i<n;i++) s1[i]=s1[i-1]+col[0][i],s2[i]=s2[i-1]+col[1][i];for(int j=2;j<n;j++) s3[j]=s3[j-1]+col[j][0],s4[j]=s4[j-1]+col[j][1];m=n-2;for(int j=1;j<=2*m-1;j++){o[j]=j<=m?col[m+2-j][2]:col[2][j-m+2];t1[j]=t1[j-1]+o[j],t2[j]=t2[j-1]+o[j]*j;}vector<ll> vec(q);for(int i=0;i<q;i++)vec[i]=calc(d[i],r[i])-calc(u[i]-1,r[i])-calc(d[i],l[i]-1)+calc(u[i]-1,l[i]-1);return vec;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/795714.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 必收藏✨免费手机铃声下载网站大公开

最推荐的方式,当然是在线网站了。1.北岛铃声网 https://www.beidaols.cn/优点:免费下载:用户可以免费获取各种手机铃声,无需支付费用。 铃声多样:提供了丰富的铃声选择,满足不同用户的个性化需求。 教程详细:提供了详细的设置苹果铃声的教程,对于不熟悉苹果手机设置的…

原神蒙德-Typora模板

基于Newsprint主题开发的一种Typora模板新建模板 打开Typora - 文件 - 偏好设置 - 外观 - 打开主题文件夹 找到其中的 Newsprint (应该有一个文件夹+一个css,都要) ,拷贝副本,重命名(我命名的是“custom”),一定要这一步,不然后期更新的时候会覆盖 修改 打开其中的 cu…

学习日历-2024/9/11

LinkList集合 底层数据结构时双链表,查询慢,首尾操作的速度是极快的,所以多了很多的首尾操作在使用迭代器或者增强for循环遍历集合的过程中,不要使用集合的方法去添加或者删除元素即可 SQL DML-添加数据 1.给指定字段添加数据 INSERT INTO 表名(字段名1,字段名2,...) VALUES(值…

真实Redmi note11t pro澎湃刷机

解决:澎湃如何刷回miui13-14系统 澎湃bl解锁后结合视频进行刷机 刷机包下载地址 刷机工具1. 备份 首先先备份当前资料小米云备份使用小米手机助手备份资料2. 澎湃bl解锁 手机打开开发者 ​​ 连接电脑usb文件传输模式 ‍ 打开澎湃bl解锁 ,双击 点我开始解锁.bat 运行以后手机会…

[python][selenium] Web UI自动化切换iframe框架以及浏览器操作切换窗口和处理弹窗

分两部分:一、页面切换iframe框架     二、浏览器操作:切换窗口、处理弹窗一、页面切换iframe框架 3种iframe的切换方法: 1、切换iframe的方法:switch_to.frame  入参有4种:  1.1、id  1.2、name  1.3、index索引  1.4、iframe元素对象 2、返回主文档(最外…

js的常用类2

1.js的常用类DOM,将js,html中的各种文档,元素,标签等等封装成方法;和类

【openmediavault】更改端口后急救方案

首先,如果你手贱改了这个 导致你登陆不了的话,不要慌 找到你的控制台,我的是树莓派 将你的树莓派设置成root模式,如果服务器本身就是root就不用设置 树莓派设置root方法sudo su然后omv-firstaid 这个界面点ok即可,加载会有点慢是正常的现象#videoTogetherLoading { touch…

Git流程学习

初始化仓库特别要注意如果初始化仓库时勾选了图中第一个红框(即添加README仓库描述),它会给出下面红框的提示即将main作为默认分支,该部分的示例以此种方式初始化仓库。 注:2020年10月后GitHub宣布新建项目的默认分支将从master逐步改为main。以前一些教程给出的命令一般都…

.NET 9 RC1 正式发布

.NET 9 RC1 是 .NET 9 的第一个候选发布版本(Release Candidate),标志着该版本接近最终发布。根据Github 上相关的内容,我们可以总结出以下几点:新功能和改进:在 .NET 9 RC1 中,引入了许多新的功能和改进。例如,ASP.NET Core 在此版本中进行了多项更新,包括 SignalR 分…

监管动态| 网络空间协会首次发布合规常用APP清单,是否会有第二批?

9月10日中国网络空间安全协会官网发布公告,协会组织指导网上购物、地图导航、浏览器、新闻资讯、在线影音、电子图书、拍摄美化、云盘、短视频、演出票务共10类62款App运营方,对照《中华人民共和国网络安全法》《中华人民共和国个人信息保护法》《常见类型移动互联网应用程序…

时间embedding

左边的公式和 time_embedding(1) 的区别在于它们表示的维度不同。公式中的左边部分是一个概括性公式,用来说明如何为每个时间步 ( t ) 生成时间嵌入。而具体的 time_embedding(1) 展示的是当 ( t = 1 ) 时,如何生成一个更长维度的时间嵌入向量。 1. 左边公式的含义: 左边的公…

微信小程序开发系列8----页面配置--事件绑定

源码获取方式(免费):(1)登录-注册:http://resources.kittytiger.cn/(2)签到获取积分(3)搜索:6-wxmlevent事件绑定