题面:https://www.lydsy.com/JudgeOnline/problem.php?id=3489
题解
可持久化树套树太难写了,直接用KD树水过去。。。
对于每个点,找到前一个跟它的值相同的点pre,与后一个跟它的值相同的点nxt
那么点 i 能够更新答案的充要条件就是:l<=i<=r ,prei<l , nxti>r
然后把一个点的坐标设为3维,分别为(i,prei,nxti)
写一个支持查询最大值的3D树就可以了
代码:(时间复杂度较高 24548ms)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
char c;int num=0,flg=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
return num*flg;
}
#define N 100005
#define lc ch[i][0]
#define rc ch[i][1]
const int INF=1000000000;
int D;
int ch[N][2],rt,tot;
int tmp[N],cnt;
int a[N][3],mi[N][3],mx[N][3];
int mxx[N],val[N];
int qmi[3],qmx[3];
int pre[N],nxt[N],tong[N];
inline void pushup(int i)
{
for(int j=0;j<3;j++){
mi[i][j]=min(min(mi[lc][j],mi[rc][j]),a[i][j]);
mx[i][j]=max(max(mx[lc][j],mx[rc][j]),a[i][j]);
}
mxx[i]=max(max(mxx[lc],mxx[rc]),val[i]);
}
inline bool cmp(const int &x,const int &y){return a[x][D]<a[y][D];}
void build(int &i,int l,int r,int d)
{
int mid=(l+r)>>1;D=d;
nth_element(tmp+l,tmp+mid,tmp+r+1,cmp);
i=tmp[mid];lc=rc=0;
if(l<mid)build(lc,l,mid-1,(d+1)%3);
if(r>mid)build(rc,mid+1,r,(d+1)%3);
pushup(i);
}
int ans;//long long con;
void query(int &i)
{
//con++;
if(!i)return;
if(mxx[i]<=ans)return;
if(mx[i][0]<qmi[0]||qmx[0]<mi[i][0]
||mx[i][1]<qmi[1]||qmx[1]<mi[i][1]
||mx[i][2]<qmi[2]||qmx[2]<mi[i][2])
return;
if(qmi[0]<=mi[i][0]&&mx[i][0]<=qmx[0]
&&qmi[1]<=mi[i][1]&&mx[i][1]<=qmx[1]
&&qmi[2]<=mi[i][2]&&mx[i][2]<=qmx[2])
{ans=max(ans,mxx[i]);return;}
if(qmi[0]<=a[i][0]&&a[i][0]<=qmx[0]
&&qmi[1]<=a[i][1]&&a[i][1]<=qmx[1]
&&qmi[2]<=a[i][2]&&a[i][2]<=qmx[2])
ans=max(ans,val[i]);
query(lc);query(rc);
}
//#include<ctime>
//double c1;
int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
//c1=clock();
mi[0][0]=mi[0][1]=mi[0][2]=INF;
mx[0][0]=mx[0][1]=mx[0][2]=-INF;
int n,m,i,l,r,x,y;
n=gi();m=gi();
for(i=1;i<=n;i++){
x=gi();val[i]=x;
pre[i]=tong[x];
nxt[tong[x]]=i;
tong[x]=i;
}
for(i=1;i<=n;i++)if(tong[i])
nxt[tong[i]]=n+1;
for(i=1,tot=n;i<=n;i++){
a[i][0]=i;a[i][1]=pre[i];a[i][2]=nxt[i];
tmp[++cnt]=i;
}
build(rt,1,cnt,0);
for(i=1;i<=m;i++){
x=gi();y=gi();
l=min((x+ans)%n+1,(y+ans)%n+1);
r=max((x+ans)%n+1,(y+ans)%n+1);
//l=x;r=y;
ans=0;
qmi[0]=l;qmx[0]=r;
qmi[1]=-INF;qmx[1]=l-1;
qmi[2]=r+1;qmx[2]=INF;
query(rt);
printf("%d\n",ans);
}
//freopen("CON","w",stdout);
//printf("%.3fs\n",(clock()-c1)/1000);
//printf("%lld\n",con);
}