CF 341D Iahub and Xors 题解

本题类似普通二维树状数组,只不过是把操作改为异或。

令 $d_{i,j}$ 为二维数组异或意义下的差分数组,则 $(x1,y1)$ 至$(x2,y2)$ 的异或和为:

$$\sum^{\text{xor}}_{x1 \le i \le x2} \sum^{\text{xor}}_{y1 \le j \le y2} \sum^{\text{xor}}_{1 \le k \le i} \sum^{\text{xor}}_{1 \le l \le j} d_{k,l}$$

由于异或的性质 $x\ \text{xor}\ x=0$,且每个 $d_{k,l}$ 最多出现 $(x-\max(x1,k)+1)(y-\max(y1,l)+1)$ 次,所以只要关注后者的奇偶性即可。

又因为其奇偶性与其下标的奇偶性有关,故我们维护四个二维树状数组。

//CF341D. Iahub and Xors
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lowbit(x) ((x)&-(x))
int n,m,d[2][2][1005][1005];
void add(int x,int y,ll c)
{
	for(int i=x;i<=n;i+=lowbit(i))
	{
		for(int j=y;j<=n;j+=lowbit(j))
		{
			d[x&1][y&1][i][j]^=c;
		}
	}
	return;
}
ll sum(int x,int y)
{
	ll res=0;
	for(int i=x;i;i-=lowbit(i))
	{
		for(int j=y;j;j-=lowbit(j))
		{
			res^=d[x&1][y&1][i][j];
		}
	}
	return res;
}
int main()
{
	int op,xa,ya,xb,yb;
	ll w;
	scanf("%d%d",&n,&m);
	while(m--)
	{
		scanf("%d%d%d%d%d",&op,&xa,&ya,&xb,&yb);
		if(op==1)
		{
			printf("%lld\n",sum(xb,yb)^sum(xb,ya-1)^sum(xa-1,yb)^sum(xa-1,ya-1));
		}
		else
		{
			scanf("%lld",&w);
			add(xa,ya,w);
			add(xa,yb+1,w);
			add(xb+1,ya,w);
			add(xb+1,yb+1,w);
		}
	}
	return 0;
}
/*
 * CF
 * https://codeforces.com/problemset/problem/341/D
 * C++20 -O0
 * 2022.9.13
 */

 

posted @ 2022-09-13 20:12  Day_Dreamer_D  阅读(305)  评论(0)    收藏  举报