AlenaNuna

导航

可持久化+Trie || BZOJ 3261最大异或和 || Luogu P4735 最大异或和

题面:最大异或和

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 const int maxn=(3e5)+50,maxm=maxn;
 6 int N,M,A[maxn<<1],rt[maxn<<1],cnt=0,X,L,R,ans;
 7 char o[5];
 8 struct Trie{int cnt,son[3];}tr[maxn*80];
 9 inline void Insert(int u,int x,int a,int t){
10     if(t<0)return;
11     int w=(a&(1<<t))>0;
12     tr[x].son[!w]=tr[u].son[!w];
13     tr[x].son[w]=++cnt;
14     tr[tr[x].son[w]].cnt=tr[tr[u].son[w]].cnt+1;
15     Insert(tr[u].son[w],tr[x].son[w],a,t-1);
16     return;
17 }
18 inline void Query(int u,int x,int a,int t){
19     if(t<0)return;
20     int w=(a&(1<<t))>0;
21     w=!w;
22     if(tr[tr[x].son[w]].cnt>tr[tr[u].son[w]].cnt){
23         ans+=1<<t;
24         Query(tr[u].son[w],tr[x].son[w],a,t-1);
25     }
26     else Query(tr[u].son[!w],tr[x].son[!w],a,t-1);
27     return;
28 }
29 int main(){
30     scanf("%d%d",&N,&M);
31     Insert(0,rt[0]=++cnt,0,25);//
32     for(int i=1;i<=N;i++){
33         scanf("%d",&X);
34         A[i]=A[i-1]^X;
35         Insert(rt[i-1],rt[i]=++cnt,A[i],25);
36     }
37     while(M--){
38         scanf("%s",o);
39         if(o[0]=='A'){
40             scanf("%d",&X);
41             N++;
42             A[N]=A[N-1]^X;
43             Insert(rt[N-1],rt[N]=++cnt,A[N],25);
44         }
45         else{
46             scanf("%d%d%d",&L,&R,&X);
47             L--;R--;
48             ans=0;
49             if(L-1>=0)Query(rt[L-1],rt[R],A[N]^X,25);
50             else Query(0,rt[R],A[N]^X,25);
51             printf("%d\n",ans);
52         }
53     }
54     return 0;
55 }

By:AlenaNuna

posted on 2019-06-18 14:01  AlenaNuna  阅读(151)  评论(0编辑  收藏  举报