您的位置:首页 > 其它

4260: Codechef REBXOR

2017-07-21 16:16 176 查看


做法:

维护异或和 由异或的性质 如果要找一个区间异或最大值的话 一定是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
,l
,r
,vt
;
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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: