[BZOJ3261]最大异或和
设b[i]=a[1]^a[2]^...^a[i],所以题目所求可以转化为b[p-1]^b[n]^x,于是可持久化trie树lg。。。
fatheryoung的题解太美,在这里@一下http://www.cnblogs.com/y7070/p/5000471.html
1 #include<stdio.h> 2 3 #define maxd 2 4 #define maxn 300005 5 int tot,mark[maxn*2*24],trie[maxn*2*24][2],root[maxn*2]; 6 7 int build(int x,int val){ 8 int y,tmp; 9 tmp=y=++tot; 10 for(int i=maxd;i>=0;i--){ 11 trie[y][0]=trie[x][0]; 12 trie[y][1]=trie[x][1]; 13 mark[y]=mark[x]+1; 14 int s=(val>>i)&1; 15 x=trie[x][s]; 16 trie[y][s]=++tot; 17 y=trie[y][s]; 18 } 19 mark[y]=mark[x]+1; 20 return tmp; 21 } 22 int query(int x,int y,int val){ 23 int ans=0; 24 for(int i=maxd;i>=0;i--){ 25 int s=(val>>i)&1; 26 if(mark[trie[y][s^1]]-mark[trie[x][s^1]]) 27 ans+=(1<<i),x=trie[x][s^1],y=trie[y][s^1]; 28 else x=trie[x][s],y=trie[y][s]; 29 } 30 return ans; 31 } 32 int main(){ 33 freopen("1.in","r",stdin); 34 int n,m,a,b,c; 35 char op[5]; 36 scanf("%d%d",&n,&m); 37 int Bn=0; 38 for(int i=1;i<=n;i++){ 39 scanf("%d",&a); 40 root[i]=build(root[i-1],Bn); 41 Bn^=a; 42 } 43 root[++n]=build(root[n-1],Bn); 44 for(int i=1;i<=m;i++){ 45 scanf("%s",op); 46 if(op[0]=='A'){ 47 scanf("%d",&a); 48 Bn^=a; 49 root[++n]=build(root[n-1],Bn); 50 } 51 else{ 52 scanf("%d%d%d",&a,&b,&c); 53 printf("%d\n",query(root[a-1],root[b],c^Bn)); 54 } 55 } 56 return 0; 57 }