BZOJ 4260 Codechef REBXOR(字典树)
题意
N<=4*105
题解
看起来一副不可做的样子是吧,,,
如果只看前半部分的式子呢?
再看看后半部分...
发现 前缀异或一下 trie树上查一查 后缀异或一下 trie树上查一查
F[i]表示r1<=i的最大值 G[i]为l2>=i的最大值 两部分相加 搞定~
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<cstdio> 5 #include<algorithm> 6 using namespace std; 7 const int N=401001; 8 struct tree{ 9 int nxt[4]; 10 }tr[N*35]; 11 int n,c[N],f[N],g[N],ans,sum,tot; 12 inline void insert(int a){ 13 int now=0,z; 14 for(int i=31;i>=1;i--){ 15 if(a&(1<<(i-1)))z=1; 16 else z=0; 17 if(!tr[now].nxt[z]){ 18 tr[now].nxt[z]=++tot; 19 memset(tr[tot].nxt,0,sizeof(tr[tot].nxt)); 20 } 21 now=tr[now].nxt[z]; 22 } 23 } 24 inline int check(int x){ 25 int tmp=0; 26 int now=0,z; 27 for(int i=31;i>=1;i--){ 28 if(x&(1<<(i-1)))z=1; 29 else z=0; 30 if(tr[now].nxt[!z]){ 31 tmp=(tmp<<1)+1; 32 now=tr[now].nxt[!z]; 33 } 34 else{ 35 tmp=tmp<<1; 36 now=tr[now].nxt[z]; 37 } 38 } 39 return tmp; 40 } 41 void init(){ 42 memset(tr[0].nxt,0,sizeof(tr[0].nxt)); 43 tot=0; 44 } 45 int main(){ 46 scanf("%d",&n); 47 insert(0); 48 for(int i=1;i<=n;i++){ 49 scanf("%d",&c[i]); 50 sum^=c[i]; 51 f[i]=f[i-1]; 52 f[i]=max(f[i],check(sum)); 53 insert(sum); 54 } 55 init(); 56 sum=0; 57 insert(0); 58 for(int i=n;i>=1;i--){ 59 sum^=c[i]; 60 g[i]=g[i+1]; 61 g[i]=max(g[i],check(sum)); 62 insert(sum); 63 } 64 for(int i=1;i<=n-1;i++){ 65 ans=max(ans,f[i]+g[i+1]); 66 } 67 printf("%d",ans); 68 return 0; 69 }