Codeforces1270I Xor on Figures

Description

有一个 2k×2k 的矩阵 A,行列从 0 开始标号,有两个长度为 t 的序列 x,y

你需要通过若干次操作使得整个矩阵 A 全为 0

一次操作需要三个参数 (p,q,w),会给所有 A[(xi+p)mod2k][(yi+q)mod2k] 异或上 w

求最小的操作次数。

k9,t99t 为奇数。

Solution

设矩阵 F 满足在所有 (xi,yi) 处值为 1 而其它位置为 0

考察一下题目中给出的操作的形式和二维循环卷积是类似的,那么可以定义一种新的乘法:

F×G=HHi,j=a,bc,d[a+bimod2k][c+djmod2k]Fa,c×Gb,d

此时问题变成了找到一个矩阵 G 满足 F×G=A,其中 A 是题目中给定的矩阵

观察到上面定义的 F 矩阵在进行乘方运算时在异或运算的配合下有非常好的性质:除了自乘之外所有乘法结果会被 两次,也就是说 F2i 满足在且仅在 F[2ix%2k][2iy%2k] 处为 1

那么不难发现 F1=F2k1 ,暴力进行乘法即可

注意到 F2i 中只有 t 个元素有值,复杂度就是 Θ(22kkt)

Code

const int N=512;
int k,n,m,a[N][N],f[2][N][N];
int x[N],y[N];
signed main(){
	k=read(); n=(1<<k);
	int cur=0;	
	for(int i=0;i<n;++i) for(int j=0;j<n;++j) f[cur][i][j]=read();
	m=read();
	rep(i,1,m) x[i]=read()-1,y[i]=read()-1;
	for(int e=0;e<k;++e){
		for(int i=0;i<n;++i) for(int j=0;j<n;++j) f[cur^1][i][j]=0;
		for(int t=1;t<=m;++t){
			for(int i=0;i<n;++i){
				for(int j=0;j<n;++j){
					f[cur^1][(i+x[t])&(n-1)][(j+y[t])&(n-1)]^=f[cur][i][j];
				}
			}
		}
		rep(i,1,m) x[i]=(x[i]*2)&(n-1),y[i]=(y[i]*2)&(n-1);
		cur^=1;
	}
	int ans=0;
	for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(f[cur][i][j]) ++ans;
	print(ans);
	return 0;
}
posted @   没学完四大礼包不改名  阅读(67)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示