看到异或就去想前缀和(⊙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 ",ans); 54 }
4260: Codechef REBXOR
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 461 Solved: 206
[Submit][Status][Discuss]
Description
Input
输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。
Output
输出一行包含给定表达式可能的最大值。
Sample Input
5
1 2 3 1 2
1 2 3 1 2
Sample Output
6
HINT
满足条件的(l1,r1,l2,r2)有:(1,2,3,3),(1,2,4,5),(3,3,4,5)。
对于100%的数据,2 ≤ N ≤ 4*105,0 ≤ Ai ≤ 109。