【BZOJ2741】L-分块+可持久化trie

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,blocksiz,a[12010],pre[12010],suf[12010],block[12010],totp,tot;
int rt[12010]={0},nowrt[12010]={0},mx[120][12010]={0};
int sum[400010]={0},ch[400010][2]={0};

void insert(int v,int last,int x,bool mode)
{
sum[v]=sum[last]+1;
for(int i=30;i>=0;i--)
{
bool f=(x&(1<<i));
if (mode) ch[v][f]=++totp;
else ch[v][f]=++tot;
ch[v][!f]=ch[last][!f];
v=ch[v][f];
last=ch[last][f];
sum[v]=sum[last]+1;
}
}

int query(int v,int last,int x)
{
int ans=0;
for(int i=30;i>=0;i--)
{
ans<<=1;
bool f=(x&(1<<i));
f=!f;
if (sum[ch[v][f]]-sum[ch[last][f]]>0) ans++;
else f=!f;
v=ch[v][f];
last=ch[last][f];
}
return ans;
}

void init()
{
totp=5000;
for(int i=0;(i+1)*blocksiz<=n;i++)
{
tot=0;
ch[1][0]=ch[1][1]=0;
nowrt[(i+1)*blocksiz-1]=0;
for(int j=(i+1)*blocksiz;j<=n;j++)
{
nowrt[j]=++tot;
insert(nowrt[j],nowrt[j-1],suf[j],0);
mx[i][j]=max(mx[i][j-1],query(nowrt[j],0,suf[j+1]));
}
}
for(int i=1;i<=n;i++)
{
rt[i]=++totp;
insert(rt[i],rt[i-1],pre[i],1);
}
}

int solve(int L,int R)
{
int ans=0;
if (block[L]==block[R])
{
tot=0;
nowrt[L-1]=0;
for(int i=L;i<=R;i++)
{
nowrt[i]=++tot;
insert(nowrt[i],nowrt[i-1],suf[i],0);
ans=max(ans,query(nowrt[i],0,suf[i+1]));
}
}
else
{
ans=mx[block[L]][R];
for(int i=L;i<(block[L]+1)*blocksiz;i++)
ans=max(ans,query(rt[R],rt[(block[L]+1)*blocksiz-1],pre[i-1]));
tot=0;
nowrt[L-1]=0;
for(int i=L;i<(block[L]+1)*blocksiz;i++)
{
nowrt[i]=++tot;
insert(nowrt[i],nowrt[i-1],suf[i],0);
ans=max(ans,query(nowrt[i],0,suf[i+1]));
}
}
return ans;
}

int main()
{
scanf("%d%d",&n,&m);
blocksiz=(int)sqrt(n)+1;
pre[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
block[i]=i/blocksiz;
pre[i]=pre[i-1]^a[i];
}
suf[n+1]=0;
for(int i=n;i>=1;i--)
suf[i]=suf[i+1]^a[i];
init();

int lastans=0;
for(int i=1;i<=m;i++)
{
int x,y,l,r;
scanf("%d%d",&x,&y);
x=((ll)x+(ll)lastans)%(ll)n+1;
y=((ll)y+(ll)lastans)%(ll)n+1;
l=min(x,y),r=max(x,y);
printf("%d\n",lastans=solve(l,r));
}

return 0;
}
posted @ 2018-09-12 16:21  Maxwei_wzj  阅读(86)  评论(0编辑  收藏  举报