Description
Input
输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。
Output
输出一行包含给定表达式可能的最大值。
dp求出:
对每个r1,A[l1]^A[l1+1]^...^A[r1]的最大值
对每个l2,A[l2]^A[l2+1]^...^A[r2]的最大值
对每个i,A[l1]^A[l1+1]^...^A[r1]的最大值lm[i] (r1≤i,1≤i≤n)
对每个i,A[l2]^A[l2+1]^...^A[r2]的最大值rm[i] (l2≥i,1≤i≤n)
ans=max{lm[i]+rm[i+1]} (1≤i<n)
暴力求复杂度为O(n3),预处理异或前缀和后缀和可降至O(n2)
再用trie优化取最大值的过程可达到O(32n)
#include<cstdio> const int N=400005; int n,ans=0; int v[N]; int ls[N],rs[N]; int lm[N],rm[N]; struct node{ node*ch[2]; node(){ ch[0]=ch[1]=0; } }; node ns[64*N]; int np=0; inline node*new_node(){ return ns+np++; } struct trie{ node*rt; trie(){ rt=new_node(); } void insert(int x){ node*w=rt; for(int i=30;i>=0;i--){ int a=x>>i&1; if(w->ch[a])w=w->ch[a]; else w=w->ch[a]=new_node(); } } int max(int x){ int v=0; node*w=rt; for(int i=30;i>=0;i--){ int a=(x>>i&1)^1; if(w->ch[a])w=w->ch[a],v|=a<<i; else w=w->ch[a^1],v|=(a^1)<<i; } return v^x; } }; trie tr; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",v+i); ls[i]=ls[i-1]^v[i]; } for(int i=n;i>=1;i--)rs[i]=rs[i+1]^v[i]; for(int i=1;i<n;i++){ tr.insert(rs[i]); lm[i]=tr.max(rs[i+1]); } tr=trie(); for(int i=n;i>1;i--){ tr.insert(ls[i]); rm[i]=tr.max(ls[i-1]); } for(int i=2;i<n;i++){ if(lm[i]<lm[i-1])lm[i]=lm[i-1]; } for(int i=n-1;i>1;i--){ if(rm[i]<rm[i+1])rm[i]=rm[i+1]; } for(int i=1;i<n;i++){ if(lm[i]+rm[i+1]>ans)ans=lm[i]+rm[i+1]; } printf("%d",ans); return 0; }