可持久化树套树
发现这是一个多维偏序,可持久化树套树即可。
#include<cstdio>
#include<algorithm>
#define N 100005
using namespace std;
namespace runzhe2000
{
int read()
{
int r = 0; char c = getchar();
for(; c < '0' || c > '9'; c = getchar());
for(; c >='0' && c <='9'; r = r*10+c-'0', c = getchar());
return r;
}
int n, m, a[N], lastvis[N], pre[N], next[N], end[N], rk[N];
struct seg0
{
seg0 *ch[2]; int v;
}mem0[N*350], *tot0, *null0;
int query0(seg0 *x, int l, int r, int ql, int qr)
{
if(ql <= l && r <= qr) return x->v; int mid = (l+r)>>1, ret = 0;
if(ql <= mid) ret = max(ret, query0(x->ch[0], l,mid,ql,qr));
if(mid < qr) ret = max(ret, query0(x->ch[1], mid+1,r,ql,qr));
return ret;
}
void modi0(seg0 *x, seg0 *y, int l, int r, int p, int val)
{
x->v = max(x->v, val); if(l == r){ return;} int mid = (l+r)>>1;
if(p <= mid)
{
seg0 *tmp = ++tot0; *tmp = *y->ch[0];
modi0(tmp,y->ch[0],l,mid,p,val);
x->ch[0] = tmp;
}
else
{
seg0 *tmp = ++tot0; *tmp = *y->ch[1];
modi0(tmp,y->ch[1], mid+1,r,p,val);
x->ch[1] = tmp;
}
}
struct seg1
{
seg1 *ch[2]; seg0 *v;
}mem1[N*40], *tot1, *root[N], *null1;
int query1(seg1 *x, int l, int r, int ql, int qr, int qql, int qqr)
{
if(ql <= l && r <= qr) return query0(x->v,0,n+1,qql,qqr); int mid = (l+r)>>1, ret = 0;
if(ql <= mid) ret = max(ret, query1(x->ch[0], l,mid,ql,qr,qql,qqr));
if(mid < qr) ret = max(ret, query1(x->ch[1], mid+1,r,ql,qr,qql,qqr));
return ret;
}
void modi1(seg1 *x, seg1 *y, int l, int r, int p, int p2, int val)
{
seg0 *tmp = ++tot0; *tmp = *y->v;
modi0(tmp, y->v, 0, n+1, p2, val);
x->v = tmp;
if(l == r) return; int mid = (l+r)>>1;
if(p <= mid)
{
seg1 *tmp = ++tot1; *tmp = *y->ch[0];
modi1(tmp,y->ch[0],l,mid,p,p2,val);
x->ch[0] = tmp;
}
else
{
seg1 *tmp = ++tot1; *tmp = *y->ch[1];
modi1(tmp,y->ch[1], mid+1,r,p,p2,val);
x->ch[1] = tmp;
}
}
void init()
{
null0 = tot0 = mem0; null0->ch[0] = null0->ch[1] = null0; null0->v = 0;
null1 = tot1 = mem1; null1->ch[0] = null1->ch[1] = null1; null1->v = null0;
root[0] = null1;
}
bool cmp(int a, int b){return pre[a] < pre[b];}
void main()
{
n = read(), m = read();
for(int i = 1; i <= n; i++)
{
pre[i] = lastvis[a[i] = read()];
lastvis[a[i]] = i;
}
for(int i = 1; i <= n; i++) lastvis[a[i]] = n+1;
for(int i = n; i; i--)
{
next[i] = lastvis[a[i]];
lastvis[a[i]] = i;
rk[i] = i;
}
init(); sort(rk+1, rk+1+n, cmp);
for(int i = 1; i <= n; i++)
{
root[i] = ++tot1, *root[i] = *root[i-1]; end[pre[rk[i]]] = i;
modi1(root[i], root[i-1], 0, n+1, next[rk[i]], rk[i], a[rk[i]]);
}
for(int i = 1; i <= n; i++) end[i] = max(end[i], end[i-1]);
int ans = 0, x, y, l, r;
for(int i = 1; i <= m; i++)
{
x = read(), y = read();
l = min((x+ans)%n+1, (y+ans)%n+1);
r = max((x+ans)%n+1, (y+ans)%n+1);
printf("%d\n",ans = query1(root[end[l-1]],0,n+1,r+1,n+1,l,r));
}
}
}
int main()
{
runzhe2000::main();
}