[bzoj3261]最大异或和[可持久化trie树]

因为要求异或和最大,所以可以考虑从高位开始,向低位枚举尽可能接近~x的值,所以以二进制位为关键字,建立可持久化trie树,根据异或和的性质,XOR_SUM{i,j}=XOR_SUM{1,j} xor XOR_SUM{1,i-1},所以查询问题也可以解决了。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <ctime>
 8 
 9 using namespace std;
10 
11 struct    TRIE
12 {
13     int    son[2],val;
14 }trie[25000000];
15 
16 int    n,m,tot,Sum[610000];
17 int    root[610000],a[610000];
18 
19 void    Insert(const int root_l,int& root_r,const int d,const int step)
20 {
21     trie[root_r=++tot]=trie[root_l];
22     trie[root_r].val++;
23     if(step<0)return ;
24     int    p=(d>>step)&1;
25     Insert(trie[root_l].son[p],trie[root_r].son[p],d,step-1);
26     return ;
27 }
28 
29 int    Query(const int d,const int root_l,const int root_r,const int step)
30 {
31     if(step<0)return 0;
32     int    p=(d>>step)&1;
33     if(trie[trie[root_r].son[p^1]].val-trie[trie[root_l].son[p^1]].val)
34         return (1<<step)+Query(d,trie[root_l].son[p^1],trie[root_r].son[p^1],step-1);
35     return Query(d,trie[root_l].son[p],trie[root_r].son[p],step-1);
36 }
37 
38 int main()
39 {
40     int    i,x,l,r;
41     char    op[10];
42 
43     scanf("%d%d",&n,&m);
44     n++;
45     for(i=2;i<=n;++i)scanf("%d",&a[i]);
46     for(i=1;i<=n;++i)Sum[i]=Sum[i-1]^a[i];
47     for(i=1;i<=n;++i)Insert(root[i-1],root[i],Sum[i],23);
48     
49     for(i=1;i<=m;++i)
50     {
51         scanf("%s",op);
52         if(op[0]=='A')
53         {
54             n++;
55             scanf("%d",&a[n]);
56             Sum[n]=Sum[n-1]^a[n];
57             Insert(root[n-1],root[n],Sum[n],23);
58         }
59         else
60         {
61             scanf("%d%d%d",&l,&r,&x);
62             printf("%d\n",Query(Sum[n]^x,root[l-1],root[r],23));
63         }
64     }
65 
66     return 0;
67 }

 

posted @ 2015-12-31 02:13  Gster  阅读(759)  评论(0编辑  收藏  举报