4260: Codechef REBXOR

来源:互联网 发布:c语言包括哪些 编辑:程序博客网 时间:2024/05/16 07:43

做法:

维护异或和 由异或的性质 如果要找一个区间异或最大值的话 一定是sum[r+1]^sum[l] 

这样l之前的数被异或了两次就消失了。 剩下则是l到r的异或值。

可以从左到右维护一次l[]然后清0 

从右到左维护一次r[]

最后求一下max

#include<stdio.h>#include<iostream>#include<string.h>#define me(x) memset(x,0,sizeof(x))#define LL long long#define close() ios::sync_with_stdio(0); cin.tie(0);using namespace std;const int N=4e5+10;int next[N*32][2];LL val[N*32];int st,v[N],l[N],r[N],vt[N];void init(){    me(next[0]);    me(val);    st=1;    me(vt);}void insert(LL x){    int u=0;    for(int i=32;i>=0;i--)    {        int c=((x>>i)&1);        if(!next[u][c])        {            me(next[st]);            next[u][c]=st++;        }        u=next[u][c];        ++val[u];    }}void _delete(LL x){    int u=0;    for (int i=32; i>=0; --i)    {        int c=((x>>i)&1);        u=next[u][c];        --val[u];    }}int query(LL x){    int t=0;    int ans=0;    for(int i=32;i>=0;i--)    {        int k=((x>>i)&1);        if(k==1)        {            if(next[t][0]&&val[next[t][0]])            {                ans+=1<<i;                t=next[t][0];            }            else t=next[t][1];        }        else        {            if(next[t][1]&&val[next[t][1]])            {                ans+=1<<i;                t=next[t][1];            }            else t=next[t][0];        }    }    return ans;}int main(){    int n;    init();    close();    cin>>n;    for(int i=1;i<=n;i++)        cin>>v[i];    for(int i=1;i<=n;i++)        vt[i]=v[i]^vt[i-1];    vt[0]=0;vt[n+1]=0;    for(int i=0;i<=n;i++)    {        l[i]=max(l[i-1],query(vt[i]));        insert(vt[i]);    }    init();    for(int i=n;i>0;i--)        vt[i]=v[i]^vt[i+1];    for(int i=n+1;i>=1;i--)    {        r[i]=max(query(vt[i]),r[i+1]);        insert(vt[i]);    }    int ans=0;    for(int i=1;i<n;i++)        ans=max(ans,l[i]+r[i+1]);    cout<<ans<<endl;}


原创粉丝点击