F - Sequence
Oldjang has a sequence A of length n , the i t h number in which is A i . He defined a function f ( l , r ) = a l ⊕ a l + 1 ⊕ ⋯ ⊕ a r . It is simple for the cleverest boy oldjang to calculate the function, so he wants to make the problem more difficult for fun. He will perform two operations: The operation expressed as " 0 x y ", which means he changes the x t h number to y ; The operation expressed as " 1 l r ", which means he wants to calculate the function F ( l , r ) . F ( l , r ) = f ( l , l ) ⊕ f ( l , l + 1 ) ⊕ ⋯ ⊕ f ( l , r ) ⊕ f ( l + 1 , l + 1 ) ⊕ ⋯ f ( l + 1 , r ) ⊕ ⋯ ⊕ f ( r , r ) . That means F ( l , r ) equals to the x or sum of all f ( i , j ) satisfied l ≤ i ≤ j ≤ r . Oldjang thinks the problem is still too simple for him, so he gives this task to you.
Input
The first line contains a integers T ( 1 ≤ T ≤ 10 ) — the number of test cases . The second line contains two integers n , m ( 1 ≤ n , m ≤ 10 5 ) , which means the sequence has n numbers and oldjang has m operations. The next line contains n integers — the sequence A . In the following m lines, each line contains three integers " 0 x y " or " 1 l r " ,descriping a operation. Output
For each test case, print one line containing "Case # x : " first, where x is the test case number (starting from 1 ). Then output the answer after each the operations of second type.
Sample Input
1
3 3
1 2 3
1 1 3
0 1 2
1 1 1
Sample Output
Case #1:
2
2
题意:给定数组,按照题中的公式,求出结果,另外还要对数组进行修改。
将题中的公式化简,就会发现规律,所求区间长度为偶数时,结果为零,奇数时,从左边界开始,隔项异或,输出结果。结合要进行数据修改,所以选择了线段树进行维护,将输入的数组分了两组,一组奇数,一组偶数,分别维护两数组的线段树即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+500;
struct Tree{
int val0,val1,l,r;
}t[N*4];
int a0[N],a1[N];
void undata(int p){
t[p].val0=t[p*2].val0^t[p*2+1].val0;
t[p].val1=t[p*2].val1^t[p*2+1].val1;
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].val0=a0[l];
t[p].val1=a1[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
undata(p);
}
void change0(int p,int x,int val){
if(t[p].l==t[p].r){
t[p].val0=val;
return;
}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid){
change0(p*2,x,val);
}else{
change0(p*2+1,x,val);
}
undata(p);
}
void change1(int p,int x,int val){
if(t[p].l==t[p].r){
t[p].val1=val;
return;
}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid){
change1(p*2,x,val);
}else{
change1(p*2+1,x,val);
}
undata(p);
}
int ask0(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].val0;
}
int mid=(t[p].l+t[p].r)/2;
int ans=0;
if(l<=mid){
ans=ans^ask0(p*2,l,r);
}
if(r>mid){
ans=ans^ask0(p*2+1,l,r);
}
return ans;
}
int ask1(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].val1;
}
int mid=(t[p].l+t[p].r)/2;
int ans=0;
if(l<=mid){
ans=ans^ask1(p*2,l,r);
}
if(r>mid){
ans=ans^ask1(p*2+1,l,r);
}
return ans;
}
int main(){
int T;
scanf("%d",&T);
for(int k=1;k<=T;++k){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i){
int x;
scanf("%d",&x);
if(i%2){
a1[i]=x;
a0[i]=0;
}else{
a1[i]=0;
a0[i]=x;
}
}
build(1,1,n);
printf("Case #%d:\n",k);
while(m--){
int z,x,y;
scanf("%d %d %d",&z,&x,&y);
if(z==0){
if(x%2){
change1(1,x,y);
}else{
change0(1,x,y);
}
}else{
if((y-x)%2){
printf("0\n");
}else{
if(x%2){
printf("%d\n",ask1(1,x,y));
}else{
printf("%d\n",ask0(1,x,y));
}
}
}
}
}
return 0;
}