BZOJ3261: 最大异或和

$n \leq 300000$的数列支持$m \leq 300000$个操作:在末端插入一个数;询问整个数列的所有后缀异或和中$[L,R]$这些后缀异或和,异或上数字$x$后的哪一个最大。数字$\leq 1e7$。

转前缀和,变成$pre_n \ \ xor \ \ pre_{p-1} \ \ xor x,L-1 \leq p \leq R-1$。在区间里找一个数能异或上某个数最大,干这事需要可持久化Trie。写过主席树的可以直接yy。

 1 #include<stdio.h>
 2 #include<string.h>
 3 //#include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 #define LL long long
 8 int qread()
 9 {
10     char c; int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (t=-1);
11     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t;
12 }
13 
14 //
15 
16 int n,m;
17 #define maxn 600011
18 int root[maxn];
19 struct Trie
20 {
21     struct Node{int ls,rs,cnt;}a[maxn*26];
22     int size;
23     void insert(int &x,int y,int v)
24     {
25         int w=x=++size; a[w].cnt=1;
26         for (int i=25;~i;i--)
27         {
28             int u=(v>>i)&1;
29             a[w].ls=a[y].ls; a[w].rs=a[y].rs;
30             if (u) {a[w].rs=++size; w=size; y=a[y].rs;}
31             else {a[w].ls=++size; w=size; y=a[y].ls;}
32             a[w].cnt=a[y].cnt+1;
33         }
34     }
35     int query(int x,int y,int v)
36     {
37         int ans=0;
38         for (int i=25;~i;i--)
39         {
40             int u=(v>>i)&1;
41             if (u)
42             {
43                 if (a[a[y].ls].cnt>a[a[x].ls].cnt)
44                 {
45                     ans|=(1<<i);
46                     y=a[y].ls; x=a[x].ls;
47                 }
48                 else y=a[y].rs,x=a[x].rs;
49             }
50             else
51             {
52                 if (a[a[y].rs].cnt>a[a[x].rs].cnt)
53                 {
54                     ans|=(1<<i);
55                     y=a[y].rs; x=a[x].rs;
56                 }
57                 else y=a[y].ls,x=a[x].ls;
58             }
59         }
60         return ans;
61     }
62 }t;
63 
64 int a[maxn];
65 int main()
66 {
67     n=qread(); m=qread();
68     t.insert(root[0],0,0);
69     for (int i=1,x;i<=n;i++)
70     {
71         x=qread(); a[i]=a[i-1]^x;
72         t.insert(root[i],root[i-1],a[i]);
73     }
74     
75     char c; int x,y,v;
76     while (m--)
77     {
78         while ((c=getchar())!='A' && c!='Q');
79         if (c=='A')
80         {
81             scanf("%d",&v);
82             n++; a[n]=a[n-1]^v;
83             t.insert(root[n],root[n-1],a[n]);
84         }
85         else
86         {
87             scanf("%d%d%d",&x,&y,&v);
88             printf("%d\n",t.query(x>1?root[x-2]:0,root[y-1],v^a[n]));
89         }
90     }
91     return 0;
92 }
View Code

 

posted @ 2018-05-24 18:42  Blue233333  阅读(189)  评论(0编辑  收藏  举报