2021.08.09 P6225 抑或橙子(树状数组)

重点:

1.异或用法

题意:

Janez 喜欢橙子!他制造了一个橙子扫描仪,但是这个扫描仪对于扫描的每个橙子的图像只能输出一个 3232 位整数。

他一共扫描了 nn 个橙子,但有时他也会重新扫描一个橙子,导致这个橙子的 3232 位整数发生更新。

Janez 想要分析这些橙子,他觉得异或操作非常有趣,他每次选取一个区间从 ll 至 uu,他想要得到这个区间内所有子区间的异或和的异或和。

例如 l=2,u=4l=2,u=4 的情况,记橙子序列 AA 中第 ii 个橙子的整数是 ,那么他要求的就是:

\[a_2 \oplus a_3 \oplus a_4 \oplus (a_2\oplus a_3)\oplus(a_3\oplus a_4)\oplus(a_2\oplus a_3 \oplus a_4) \]

分析:

当l,r奇偶性质不同时,[l,r]中所有元素贡献为0(偶数次),ans=0;

当l,r奇偶性质相同时,[l,r]中与l||r奇偶性质相同的会对答案产生贡献,

\[a_l\oplus a_{l+2}\oplus a_{l+3}\cdots \oplus a_r \]

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=2e5+10;
int n,m,a[N],t[2][N];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
int lowbit(int x){
	return x&-x;
}
void change(int flag,int x,int k){
	for(int i=x;i<=n;i+=lowbit(i))t[flag][i]^=k;
}
int query(int flag,int x){
	int ans=0;
	for(int i=x;i;i-=lowbit(i))ans^=t[flag][i];
	return ans;
}

int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
		change(i&1,i,a[i]);
	}
	for(int i=1;i<=m;i++){
		int op,u,v;
		op=read();u=read();v=read();
		if(op==1){
			change(u&1,u,a[u]^v);
			a[u]=v;
		}else if(op==2){
			if((u+v)&1)cout<<"0"<<endl;
			else cout<<(query(v&1,v)^query(u&1,u-1))<<endl;
		}
	}
	return 0;
}
 posted on 2021-08-09 22:19  eleveni  阅读(59)  评论(0)    收藏  举报