[BZOJ3261]最大异或和

题目大意:
  给定一个长度为$n(n\leq3\times10^5)$的数列$A(A_i\leq10^7)$,有$m(m\leq3\times10^5)$个操作,操作有2种:
    1.在A的末尾加入一个数$x$;
    2.给定$l,r,x$,找到$l\le p\le r$的$p$使得从$A_p$开始的后缀异或最大,求出这个最大值。

思路:
  令$S$表示$A$的前缀异或和,则$\oplus_{i=p}^nA_i=S_{p-1}\oplus S_n$。因此可以以$S$建立可持久化字典树,在对应区间询问与$S_n\oplus x$异或的最大值。

 1 #include<cstdio>
 2 #include<cctype>
 3 inline int getint() {
 4     register char ch;
 5     while(!isdigit(ch=getchar()));
 6     register int x=ch^'0';
 7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 8     return x;
 9 }
10 inline char getalpha() {
11     register char ch;
12     while(!isalpha(ch=getchar()));
13     return ch;
14 }
15 const int N=6e5+1,logA=24;
16 class PresistentTrie {
17     private:
18         int val[N*logA],ch[N*logA][2];
19         int sz,new_node(const int &p) {
20             val[++sz]=val[p];
21             ch[sz][0]=ch[p][0];
22             ch[sz][1]=ch[p][1];
23             return sz;
24         }
25     public:
26         int root[N];
27         void insert(int &p,const int &x,const int &d=logA-1) {
28             val[p=new_node(p)]++;
29             if(d==-1) return;
30             const bool b=x>>d&1;
31             insert(ch[p][b],x,d-1);
32         }
33         int query(const int &p,const int &q,const int &x,const int &d=logA-1) const {
34             if(d==-1) return 0;
35             const bool b=x>>d&1;
36             if(val[ch[p][!b]]-val[ch[q][!b]]) return query(ch[p][!b],ch[q][!b],x,d-1)|(1<<d);
37             return query(ch[p][b],ch[q][b],x,d-1);
38         }
39 };
40 PresistentTrie t;
41 int main() {
42     int n=getint(),m=getint(),last=0;
43     t.insert(t.root[1]=t.root[0],0);
44     for(register int i=1;i<=n;i++) {
45         t.insert(t.root[i+1]=t.root[i],last^=getint());
46     }
47     for(register int i=1;i<=m;i++) {
48         const char opt=getalpha();
49         if(opt=='A') {
50             n++;
51             t.insert(t.root[n+1]=t.root[n],last^=getint());
52         }
53         if(opt=='Q') {
54             const int l=getint(),r=getint();
55             printf("%d\n",t.query(t.root[r],t.root[l-1],last^getint()));
56         }
57     }
58     return 0;
59 }

 

posted @ 2018-03-14 14:37  skylee03  阅读(110)  评论(0编辑  收藏  举报