1. 程式人生 > >BZOJ4260: Codechef REBXOR

BZOJ4260: Codechef REBXOR

amp () online mes php ems ret get algorithm

【傳送門:BZOJ4260】


簡要題意:

  給出一個長度為n的序列

  求出l1,r1,l2,r2,使得a[l1]^a[l1+1]...a[r1]+a[l2]^a[l2+1]...a[r2]最大,且1<=l1<=r1<l2<=r2<=n


題解:

  01字典樹,get到了字典樹處理異或和的操作

  只要用貪心的思想跑就好了


參考代碼:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include
<algorithm> using namespace std; struct trie { int c[2]; }t[21000000];int tot; int now; void clean(int x) { t[x].c[0]=t[x].c[1]=0; } void bt(int d) { int x=0; for(int i=30;i>=0;i--) { int y=(d>>i)&1; if(t[x].c[y]==0) clean(++tot),t[x].c[y]=tot; x
=t[x].c[y]; } } int lmax[410000],rmax[410000]; int a[410000]; int solve(int d) { int x=0,ans=0; for(int i=30;i>=0;i--) { int y=(d>>i)&1; if(t[x].c[y^1]!=0) ans+=1<<i,x=t[x].c[y^1]; else x=t[x].c[y]; } return ans; } int main() {
int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(lmax,0,sizeof(lmax)); memset(rmax,0,sizeof(rmax)); now=0;tot=0; clean(0); bt(now); for(int i=1;i<=n;i++) { now^=a[i]; bt(now); lmax[i]=max(solve(now),lmax[i-1]); } now=0;tot=0; clean(0); bt(now); for(int i=n;i>=1;i--) { now^=a[i]; bt(now); rmax[i]=max(solve(now),rmax[i-1]); } int ans=0; for(int i=0;i<=n;i++) ans=max(ans,lmax[i]+rmax[i+1]); printf("%d\n",ans); return 0; }

BZOJ4260: Codechef REBXOR