题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4260
第一道的trie树!
用trie树求最大异或和,就是把所有元素按位建出trie树,在树上贪心找异或当前元素最大的值。本题中的元素就是每个前缀或后缀。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=4e5+5,M=35,P=N*M; int n,a[N],dg[M],top,c[P][2],tot,f[N],g[N],k,sum,ans; void cz(int x) { top=0;while(x)dg[++top]=(x&1),x>>=1; for(int i=top+1;i<=31;i++)dg[i]=0; } int query() { int now=1,ret=0; for(int i=31;i;i--) { bool d=dg[i]; if(c[now][!d])ret|=(1<<(i-1)),now=c[now][!d]; else now=c[now][d]; } return ret; } void add() { int now=1; for(int i=31;i;i--) { bool d=dg[i]; if(!c[now][d])c[now][d]=++tot; now=c[now][d]; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); tot=1;add(); for(int i=1;i<=n;i++) { sum^=a[i];cz(sum); f[i]=max(f[i-1],query()); add(); } memset(c,0,sizeof c); sum=0;tot=1;cz(0);add(); for(int i=n;i;i--) { sum^=a[i];cz(sum); g[i]=max(g[i+1],query()); add(); } ans=0; for(int i=1;i<n;i++)ans=max(ans,f[i]+g[i+1]); printf("%d ",ans); return 0; }