题目
三维偏序。
主席树套二维线段树。
namespace真舒服。
比KD树慢3倍。
AC Code:
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
int n,m,a[maxn],pre[maxn],loc[maxn];
vector<pair<int,int> >G[maxn];
namespace Seg2{
#define maxppt maxn * 20 * 19
int lc[maxppt] , rc[maxppt] , Max[maxppt] , tot;
void Insert(int &now,int l,int r,const int &pos,const int &val){
Max[++tot] = max(Max[now],val) , lc[tot] = lc[now] , rc[tot] = rc[now];
now = tot;
if(l == r) return;
int mid = (l+r) >> 1;
if(pos <= mid) Insert(lc[now],l,mid,pos,val);
else Insert(rc[now],mid+1,r,pos,val);
}
int Query(int &now,int l,int r,const int &ql,const int &qr){
if(!now || l>qr || ql>r) return 0;
if(ql<=l && r<=qr) return Max[now];
int mid = (l+r) >> 1;
return max(Query(lc[now],l,mid,ql,qr),Query(rc[now],mid+1,r,ql,qr));
}
}
namespace Seg1{
#define maxpt maxn * 20
int lc[maxpt] , rc[maxpt] , rt[maxpt] , tot;
void Insert(int &now,int l,int r,const int &pos1,const int &pos2,const int &val){
lc[++tot] = lc[now] , rc[tot] = rc[now] , rt[tot] = rt[now];
now = tot;
Seg2::Insert(rt[now],1,n+1,pos2,val);
if(l == r) return;
int mid = (l+r) >> 1;
if(pos1 <= mid) Insert(lc[now],l,mid,pos1,pos2,val);
else Insert(rc[now],mid+1,r,pos1,pos2,val);
}
int Query(int now,int l,int r,const int &ql,const int &qr,const int &ql2,const int &qr2){
if(!now || l>qr || ql>r) return 0;
if(ql<=l&& r<=qr) return Seg2::Query(rt[now],1,n+1,ql2,qr2);
int mid = (l+r) >> 1;
return max(Query(lc[now],l,mid,ql,qr,ql2,qr2),Query(rc[now],mid+1,r,ql,qr,ql2,qr2));
}
}
int rt[maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
pre[i] = loc[a[i]];
loc[a[i]] = i;
if(pre[i]) G[pre[pre[i]]].push_back(make_pair(pre[i],i));
}
for(int i=1;i<=n;i++)
if(loc[i])
G[pre[loc[i]]].push_back(make_pair(loc[i],n+1));
for(int i=0;i<=n;i++){
if(i)rt[i] = rt[i-1];
for(int j=0,siz=G[i].size();j<siz;j++)
Seg1::Insert(rt[i],1,n+1,G[i][j].first,G[i][j].second,a[G[i][j].first]);
}
int la = 0;
for(int x,y,l,r;m--;){
scanf("%d%d",&x,&y);
x = (x + la) % n + 1,
y = (y + la) % n + 1;
l = min(x,y) , r = max(x,y);
printf("%d\n",la=Seg1::Query(rt[l-1],1,n+1,l,r,r+1,n+1));
}
}