现在有一个N个整数组成的序列,这N个整数的标号分别为1, 2, ..., N,对这个序列一共进行两类操作:
① 1 x y:表示将第x个和第y个(包括x、y)整数之间的所有整数的二进制的最低位的1变为0,如果某个整数的值为0,则不对这个整数做任何改变。
② 2 x y :表示你需要回答第x个和第y个(包括x、y)整数之间的所有整数异或的结果。
现在有一个N个整数组成的序列,这N个整数的标号分别为1, 2, ..., N,对这个序列一共进行两类操作:
对于每个第②类操作,用一行输出一个整数表示回答的结果。
#include <stdio.h> #define N 10001 int n,m; int a[N]; int ans[4*N]; bool f[4*N]; void update(int cur) { int ls=cur<<1,rs=cur<<1|1; ans[cur]=ans[ls]^ans[rs]; f[cur]=f[ls]|f[rs]; } void build(int cur,int x,int y) { int mid=x+y>>1,ls=cur<<1,rs=cur<<1|1; if(x==y) { f[cur]=ans[cur]=a[x]; return; } build(ls,x,mid); build(rs,mid+1,y); update(cur); } void change(int cur,int x,int y,int s,int t) { int mid=x+y>>1,ls=cur<<1,rs=cur<<1|1; if(!f[cur]) return; if(x==y) { ans[cur]^=ans[cur]&(-ans[cur]); f[cur]=ans[cur]; return; } if(mid>=s) change(ls,x,mid,s,t); if(mid+1<=t) change(rs,mid+1,y,s,t); update(cur); } void query(int cur,int x,int y,int s,int t,int &ret) { int mid=x+y>>1,ls=cur<<1,rs=cur<<1|1; if(x>=s && y<=t) { ret^=ans[cur]; return; } if(mid>=s) query(ls,x,mid,s,t,ret); if(mid+1<=t) query(rs,mid+1,y,s,t,ret); } void solve(int opt,int x,int y) { int ret=0; if(x>y) {int tmp=x;x=y;y=tmp;} if(opt==1) change(1,1,n,x,y); else query(1,1,n,x,y,ret),printf("%d\n",ret); } int main() { int opt,x,y,i; while(~scanf("%d%d",&n,&m)) { for(i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); while(m--) { scanf("%d%d%d",&opt,&x,&y); solve(opt,x,y); } } return 0; }