BZOJ4260: Codechef REBXOR

【传送门: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;
}

 

posted @ 2018-04-16 13:48  Star_Feel  阅读(206)  评论(0编辑  收藏  举报