标签:
看到异或就去想前缀和(⊙o⊙)
这个就是正反做一遍最大异或和更新答案
最大异或就是很经典的可持久化Trie,从高到低贪心
WA: val&(1<<(base-1))得到的并不直接是1/0
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define N 400005 4 using namespace std; 5 inline int read(){ 6 int x=0,f=1;char ch=getchar(); 7 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 8 while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();} 9 return x*f; 10 } 11 int n,tot,a[N],rt[N],ch[N*40][2]; 12 int ans,now,lmx[N],rmx[N]; 13 void build(int &x,int base){ 14 x=++tot; 15 if(base==-1)return; 16 build(ch[x][0],base-1); 17 } 18 int getmx(int x,int base,int val){ 19 if(!base)return 0; 20 int t=val&(1<<(base-1));t?t=0:t=1; 21 if(ch[x][t]){return (1<<(base-1))+getmx(ch[x][t],base-1,val);} 22 else return getmx(ch[x][t^1],base-1,val); 23 } 24 void add(int pre,int &x,int base,int val){ 25 x=++tot; 26 ch[x][0]=ch[pre][0];ch[x][1]=ch[pre][1]; 27 if(base==-1)return; 28 int t=val&(1<<(base-1));t?t=1:t=0; 29 add(ch[pre][t],ch[x][t],base-1,val); 30 } 31 int main(){ 32 n=read(); 33 for(int i=1;i<=n;i++)a[i]=read(); 34 now=0;tot=0; 35 build(rt[0],31); 36 for(int i=1;i<=n;i++){ 37 rt[i]=rt[i-1]; 38 now^=a[i]; 39 lmx[i]=getmx(rt[i-1],31,now); 40 add(rt[i-1],rt[i],31,now); 41 } 42 for(int i=1;i<=n;i++)lmx[i]=max(lmx[i],lmx[i-1]); 43 now=0;tot=0; 44 memset(ch,0,sizeof(ch)); 45 build(rt[0],31); 46 for(int i=n;i;i--){ 47 now^=a[i]; 48 rmx[i]=getmx(rt[i+1],31,now); 49 add(rt[i+1],rt[i],31,now); 50 } 51 for(int i=n;i;i--)rmx[i]=max(rmx[i],rmx[i+1]); 52 for(int i=1;i<n;i++)ans=max(ans,lmx[i]+rmx[i+1]); 53 printf("%d\n",ans); 54 }
【BZOJ4260】 Codechef REBXOR 可持久化Trie
标签:
原文地址:http://www.cnblogs.com/wjyi/p/5568650.html