之前应该是做过这题的弱化版,没有强制在线随便就艹过去了
正解应该是和可持久化堆相关的东西,但是我不会啊怎么办QAQ
祭出暴力大法KD-Tree,话说我第二次写KD-Tree胡完什么都没看随便写了一发就艹过去了,这东西真JB好用
首先那个区间内的限制我们很套路地拆掉,把一个位置看作四元组\((pos,pre,nxt,val)\),分别表示位置,前驱(和这个数相同的前一个位置,后面同理),后继,权值
然后对于询问的区间\([l,r]\),一个位置可以被统计当且仅当满足\(pos\in [l,r];pre
容易发现这就是一个高维数点的板子,应该是可以通过CDQ分治再带个可持久化堆撤销来两个\(\log\)做的
PS:突然想到强制在线了CDQ个屁
emmm,所以我写KD-Tree
#include
#include
#include
#define RI register int
#define CI const int&
#define Tp template
using namespace std;
const int N=100005;
int D;
struct point
{
int w[3],val;
friend inline bool operator < (const point& A,const point& B)
{
for (RI i=0;i<3;++i) if (A.w[(D+i)%3]!=B.w[(D+i)%3])
return A.w[(D+i)%3]ans&&Mx(now).w[0]>=x&&Mi(now).w[0]<=y&&Mi(now).w[1]y;
}
public:
inline void build(int& now,CI l=1,CI r=n,CI d=0)
{
now=++tot; int mid=l+r>>1; D=d; nth_element(a+l+1,a+mid+1,a+r+1);
P(now)=Mi(now)=Mx(now)=a[mid];
if (l!=mid) build(lc(now),l,mid-1,(d+1)%3),pushup(now,lc(now));
if (r!=mid) build(rc(now),mid+1,r,(d+1)%3),pushup(now,rc(now));
}
inline void query(CI now)
{
if (!now||!judge(now)) return;
if (P(now).w[0]>=x&&P(now).w[0]<=y&&P(now).w[1]y) ans=max(ans,P(now).val);
query(lc(now)); query(rc(now));
}
#undef lc
#undef rc
#undef P
#undef Mi
#undef Mx
}KD;
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (F.read(n),F.read(m),i=1;i<=n;++i)
F.read(x),pre[i]=rst[x],nxt[rst[x]]=i,rst[x]=i,a[i].val=x;
for (i=1;i<=n;++i) a[i].w[0]=i,a[i].w[1]=pre[i],a[i].w[2]=nxt[i]?nxt[i]:n+1;
for (KD.build(rt),i=1;i<=m;++i)
{
F.read(x); F.read(y); x=(x+ans)%n+1; y=(y+ans)%n+1;
if (x>y) swap(x,y); ans=0; KD.query(rt); F.write(ans);
}
return F.flush(),0;
}