标签:
类似p3261,只是我们需要分块预处理anss[i][j]第i块到第j块的答案,然后整块的部分直接获得,零散的部分暴力。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 12001
#define MAXBIT 31
#define BN 115
int root[N],ch[N*(MAXBIT+1)][2],sz[N*(MAXBIT+1)],tot;
int query(int L,int R,int W)//询问a[L...R]中W与其的最大异或值
{
int ans=0;
L=root[L-1];R=root[R];
for(int i=MAXBIT-1;i>=0;--i)
{
int Bit=(W>>i&1^1);
if(sz[ch[R][Bit]]-sz[ch[L][Bit]]==0)
Bit^=1;
else
ans+=1<<i;
R=ch[R][Bit];
L=ch[L][Bit];
}
return ans;
}
void add(int now,int W)//先add(1,0),再add(2...n+1,a[1...n])
{
int old=root[now-1];
root[now]=++tot;
now=root[now];
for(int i=MAXBIT-1;i>=0;--i)
{
int Bit=(W>>i&1);
sz[now]=sz[old]+1;
ch[now][Bit^1]=ch[old][Bit^1];
ch[now][Bit]=++tot;
now=ch[now][Bit];
old=ch[old][Bit];
}
sz[now]=sz[old]+1;
}
int n,m,a[N],l[BN],r[BN],anss[BN][BN],num[N],sum=1;
void init()
{
for(int i=1;i<=sum;++i)
{
int res=0;
for(int j=i;j<=sum;++j)
{
for(int k=l[j];k<=r[j];++k)
res=max(res,query(l[i]-1,k-1,a[k]));
anss[i][j]=res;
}
}
}
void makeblock()
{
int sz=sqrt(n); if(!sz) sz=1;
for(;sum*sz<n;++sum)
{
l[sum]=r[sum-1]+1;
r[sum]=sum*sz;
for(int i=l[sum];i<=r[sum];++i)
num[i]=sum;
}
l[sum]=r[sum-1]+1;
r[sum]=n;
for(int i=l[sum];i<=r[sum];++i)
num[i]=sum;
}
int x,y,ans;
typedef long long ll;
ll L,R;
int main()
{
scanf("%d%d",&n,&m);
add(0,0);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
a[i]^=a[i-1];
add(i,a[i]);
}
makeblock();
init();
for(;m;--m)
{
scanf("%I64d%I64d",&L,&R);
x=(int)min((L+(ll)ans)%(ll)n+1,(R+(ll)ans)%(ll)n+1);
y=(int)max((L+(ll)ans)%(ll)n+1,(R+(ll)ans)%(ll)n+1);
ans=0;
if(num[x]+1>=num[y])
for(int i=x;i<=y;++i)
ans=max(ans,query(x-1,i-1,a[i]));
else
{
ans=anss[num[x]+1][num[y]-1];
for(int i=x-1;i<r[num[x]];++i) ans=max(ans,query(i+1,y,a[i]));
for(int i=l[num[y]];i<=y;++i) ans=max(ans,query(x-1,i-1,a[i]));
}
printf("%d\n",ans);
}
return 0;
}
【分块】【可持久化Trie】bzoj2741 【FOTILE模拟赛】L
标签:
原文地址:http://www.cnblogs.com/autsky-jadek/p/4318273.html