jzoj5382 [GDOI2018模拟9.21]数列 可持久化trie+分块
程序员文章站
2024-02-12 22:42:10
...
Description
n,q<=20000
a[i]<=10^9
Solution
今天场外体验noi刺激战场,发现我只会做T1这种送分题(⊙ˍ⊙),还没切。果然人菜还是要多读书
首先做前缀和,变成两个点的问题
与异或相关可以考虑trie。一个暴力的做法就是建可持久化trie然后枚举查询最大异或和
看到n很小一个想法就是对区间分块,预处理f[i,j]表示块i的起点到j这一段的答案,然后搞搞就可以了
如果没有强制在线可以莫队,然鹅直接莫队就有90分
Solution
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
typedef long long LL;
const int N=20005;
const int B=185;
int rec[N*60][2],root[N],sum[N*60],tot;
int st[B],ed[B],bel[N],a[N];
int wjp[B][N],ans;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
int ins(int x,int v) {
int y=++tot; int ret=y;
drp(i,29,0) {
rec[y][0]=rec[x][0];
rec[y][1]=rec[x][1];
sum[y]=sum[x]+1;
int now=(v&(1<<i))!=0;
x=rec[x][now];
y=rec[y][now]=++tot;
}
sum[y]=sum[x]+1;
return ret;
}
int query(int pre,int x,int v) {
int ret=0;
drp(i,29,0) {
int now=(v&(1<<i))!=0;
if (sum[rec[x][!now]]-sum[rec[pre][!now]]>0) {
x=rec[x][!now];
pre=rec[pre][!now];
ret+=1<<i;
} else {
x=rec[x][now];
pre=rec[pre][now];
}
// if (ret+(1<<i+1)-1<=ans) return ret;
}
return ret;
}
int main(void) {
freopen("data.in","r",stdin);
freopen("myp.out","w",stdout);
int n=read(),q=read(),t=read();
int m=sqrt(n);
root[0]=ins(0,0);
rep(i,1,n) {
a[i]=a[i-1]^read();
root[i]=ins(root[i-1],a[i]);
bel[i]=(i-1)/m+1;
if (!st[bel[i]]) st[bel[i]]=i;
ed[bel[i]]=std:: max(ed[bel[i]],i);
}
rep(i,1,m) {
rep(j,st[i],n) {
wjp[i][j]=std:: max(wjp[i][j-1],query((st[i]-1)?root[st[i]-2]:0,root[j],a[j]));
}
}
for (int lastans=0,cnt=0;q--;cnt++) {
int l=read(),r=read(); ans=0;
int x=(l+t*(LL)lastans)%n+1;
int y=(r+t*(LL)lastans)%n+1;
if (x>y) std:: swap(x,y);
int px=bel[x],py=bel[y];
if (py==px) {
rep(j,x,y) ans=std:: max(ans,query((x-1)?(root[x-2]):0,root[y],a[j]));
} else {
ans=wjp[px+1][y];
rep(j,x-1,ed[px]) ans=std:: max(ans,query((x-1)?(root[x-2]):0,root[y],a[j]));
rep(j,st[py],y) ans=std:: max(ans,query((x-1)?(root[x-2]):0,root[y],a[j]));
}
printf("%d\n", ans); lastans=ans;
}
return 0;
}