传送门~
作为简易的
K
−
d
K-d
K−d
t
r
e
e
tree
tree模板
将一个数作为一个点
(
x
,
y
,
z
)
(x,y,z)
(x,y,z)
x
x
x为该点位置,
y
y
y为左面第一个和它一样的数的位置,
z
z
z是右面第一个和他一样的数的位置
问题转化成,给定
l
l
l和
r
r
r,求一个权值最大的点,使
y
<
l
y<l
y<l
z
>
r
z>r
z>r
r
=
>
x
=
>
l
r=>x=>l
r=>x=>l
就成了在一个长方体中求一个最大的值
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstdlib>
using namespace std;
int num[200005],point[200005];
int pre[200005],nex[200005];
int cmpd,n,m,ans,lx,ly,root;
struct data{
int d[3],mx[3],mn[3],val,maxn;
int l,r;
}s[200005];
bool cmp(data r1,data r2){
return r1.d[cmpd]<r2.d[cmpd];
}
void maintain(int now){
int l=s[now].l,r=s[now].r;
for (int i=0;i<=2;i++){
if(l){s[now].mx[i]=max(s[now].mx[i],s[l].mx[i]);s[now].mn[i]=min(s[now].mn[i],s[l].mn[i]);}
if(r){s[now].mx[i]=max(s[now].mx[i],s[r].mx[i]);s[now].mn[i]=min(s[now].mn[i],s[r].mn[i]);}
}
if(l) s[now].maxn=max(s[l].maxn,s[now].maxn);
if(r) s[now].maxn=max(s[r].maxn,s[now].maxn);
}
int build(int l,int r,int d){
if(l>r) return 0;
d%=3;cmpd=d;
int mid=l+r>>1;
nth_element(s+l,s+mid,s+r+1,cmp);
for(int i=0;i<=2;i++) s[mid].mx[i]=s[mid].mn[i]=s[mid].d[i];
s[mid].l=build(l,mid-1,d+1);
s[mid].r=build(mid+1,r,d+1);
maintain(mid);
return mid;
}
bool check(int now){
if(s[now].mx[0]<lx || s[now].mn[0]>ly) return 0;
if(s[now].mn[1]>=lx) return 0;
if(s[now].mx[2]<=ly) return 0;
return 1;
}
void ch(int now){
if(s[now].d[0]>=lx && s[now].d[0]<=ly && s[now].d[1]<lx && s[now].d[2]>ly) ans=max(ans,s[now].val);
int l=s[now].l,r=s[now].r;
if(l && s[l].maxn>ans && check(l)) ch(l);
if(r && s[r].maxn>ans && check(r)) ch(r);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&num[i]);
for(int i=1;i<=n;i++) {pre[i]=point[num[i]];point[num[i]]=i;}
for(int i=1;i<=n;i++) point[i]=n+1;
for(int i=n;i>=1;i--) {nex[i]=point[num[i]];point[num[i]]=i;}
for(int i=1;i<=n;i++) {s[i].d[0]=i;s[i].d[1]=pre[i];s[i].d[2]=nex[i];s[i].val=num[i];s[i].maxn=num[i];}
root=build(1,n,0);
for(int i=1;i<=m;i++){
scanf("%d%d",&lx,&ly);
lx=(lx+ans)%n+1;
ly=(ly+ans)%n+1;
if(lx>ly) swap(lx,ly);
ans=0;ch(root);
printf("%d\n",ans);
}
return 0;
}