BZOJ 4260: Codechef REBXOR|Trie树

求出以i为结尾的前缀的最大抑或和,以i为开始的后缀最大抑或和。
然后用字典树来维护抑或出来的前缀和后缀。
似乎很水的样子

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#define T 400004
using namespace std;
int sc()
{
    int i=0; char c=getchar();
    while(c>'9'||c<'0')c=getchar();
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i;
}
int p[T*32][2],a[T],L[T],R[T];
int n,now,tot,ans;
void build(int x)
{
    int now=0;
    for(int i=1<<30;i;i>>=1)
    {
        int w=(x&i)?1:0;
        if(p[now][w])now=p[now][w];
        else now=p[now][w]=++tot;
    }
}
int cal(int x)
{
    int now=0,ans=0;
    for(int i=1<<30;i;i>>=1)
    {
        int w=(x&i)?0:1;
        if(p[now][w])
            ans|=i,now=p[now][w];
        else
            now=p[now][!w];
    }
    return ans;
}
int main()
{
    n=sc();
    for(int i=1;i<=n;i++)a[i]=sc();
    build(now=tot=0);
    for(int i=1;i<=n;i++)
    {
        now^=a[i];
        build(now);
        L[i]=cal(now);
        L[i]=max(L[i],L[i-1]);
    }
    memset(p,0,sizeof(p));
    build(now=tot=0);
    for(int i=n;i;i--)
    {
        now^=a[i];
        build(now);
        R[i]=cal(now);
        R[i]=max(R[i],R[i-1]);
        ans=max(ans,L[i-1]+R[i]);
    }
    cout<<ans;
    return 0;
}
    原文作者:Trie树
    原文地址: https://blog.csdn.net/ws_yzy/article/details/50633569
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞