BZOJ 3261 最大异或和 (可持久化01Trie)

题目大意:让你维护一个序列,支持在序列末插入一个数,支持询问$[l,r]$区间内选择一个位置$p$,使$xor\sum_{i=p}^{n}a_{i}$最大

可持久化$01Trie$裸题,把 区间异或和 转化为区间端点前缀异或和的异或值

即求$xsum_{n}\;xor\;max(xsum_{i})i\in[l-1,r-1]$的最大值

那么在可持久化$01Trie$里是$r-1$的$Trie$对$l-2$的$Trie$做差

需要先把$0$推入$Trie$里

 1 #include <cmath>
 2 #include <queue>
 3 #include <vector>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 #define N1 600100
 8 #define N2 16000100
 9 #define MM 100
10 #define ll long long
11 #define dd double  
12 #define uint unsigned int
13 #define mod 1000000007
14 #define idx(X) (X-'a')
15 using namespace std;
16 
17 int gint()
18 {
19     int ret=0,fh=1;char c=getchar();
20     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
21     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
22     return ret*fh;
23 }
24 int bin[25];
25 struct Trie{
26 int ch[N2][2],root[N1],num[N2],tot;
27 void init(){
28     tot=1;int x=1;root[0]=1;
29     for(int i=23;i>=0;i--)
30         ch[x][0]=++tot,x=ch[x][0],num[x]=1;
31 }
32 void insert(uint s,int id,int w)
33 {
34     int p,x,y;
35     root[id]=++tot;
36     x=root[id],y=root[id-1];
37     for(int i=23;i>=0;i--){
38         p=(s&bin[i])?1:0;
39         ch[x][p]=++tot;
40         ch[x][p^1]=ch[y][p^1];
41         x=ch[x][p],y=ch[y][p];
42         num[x]=num[y]+w;
43     }
44 }
45 uint query(int l,int r,uint s)
46 {
47     int x,y,sx,sy,p;uint ans=0;
48     y=l<0?0:root[l],x=root[r];
49     for(int i=23;i>=0;i--){
50         p=(s&bin[i])?1:0;
51         if(num[ch[x][p^1]]-num[ch[y][p^1]]>0){
52             x=ch[x][p^1],y=ch[y][p^1];
53             ans|=bin[i];
54         }else if(num[ch[x][p]]-num[ch[y][p]]>0){
55             x=ch[x][p],y=ch[y][p];
56         }else break;
57     }return ans;
58 }
59 }T;
60 int n,m;
61 uint a[N1],pa[N1];
62 
63 int main()
64 {
65     //freopen("t1.in","r",stdin);
66     scanf("%d%d",&n,&m);
67     for(int i=0;i<=23;i++)
68         bin[i]=(1<<i);
69     T.init();
70     for(int i=1;i<=n;i++)
71     {
72         a[i]=gint();
73         pa[i]=pa[i-1]^a[i];
74         T.insert(pa[i],i,1);
75     }
76     char str[10];
77     int l,r;uint x;
78     for(int i=1;i<=m;i++)
79     {
80         scanf("%s",str);
81         if(str[0]=='A'){
82             n++;a[n]=gint();
83             pa[n]=pa[n-1]^a[n];
84             T.insert(pa[n],n,1);
85         }else{
86             l=gint(),r=gint(),x=gint();
87             printf("%u\n",T.query(l-2,r-1,pa[n]^x));
88         }
89     }
90     return 0;
91 }

 

posted @ 2018-11-27 15:56  guapisolo  阅读(219)  评论(0编辑  收藏  举报