[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 }
View Code

 

posted @ 2015-11-27 15:40  Ngshily  阅读(145)  评论(0编辑  收藏  举报