“因为是OJ上的题,就简单点好了。” Orz
看看贴吧吧:http://tieba.baidu.com/p/2947256742#47989538012l
题目大意:区间只出现过一次的最大的数
记一下next
从左到右 删了之前的标记 再从这个点到next-1都打标记 然后就可以查询了
按一个坐标离线做强制转在线么 用主席树好了 第一次打主席树区间修改 空间两个log 不过这个的前提是标记永久化 不然就是n2了
#include
#include
#include
#include
using namespace std;
typedef long long ll;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=100005;
struct Heap{
priority_queue q,del;
void maintain() { while (!del.empty() && !q.empty() && del.top()==q.top()) del.pop(),q.pop(); }
bool empty() { return q.size()==del.size(); }
int top() { if (empty()) return 0; maintain(); return q.top(); }
void push(int x) { maintain(); q.push(x); }
void erase(int x) { maintain(); del.push(x); }
};
int ncnt,rcnt;
int root[N*120],ls[N*120],rs[N*120],maxv[N*120];
Heap T[N*4];
inline void add(int &y,int x,int pos,int l,int r,int L,int R,int v){
y=++ncnt; int mid=(l+r)>>1;
if (L<=l && r<=R)
{
T[pos].push(v);
maxv[y]=T[pos].top();
ls[y]=ls[x]; rs[y]=rs[x];
return;
}
maxv[y]=maxv[x];
if (R<=mid)
add(ls[y],ls[x],pos<<1,l,mid,L,R,v),rs[y]=rs[x];
else if (L>mid)
add(rs[y],rs[x],pos<<1|1,mid+1,r,L,R,v),ls[y]=ls[x];
else
add(ls[y],ls[x],pos<<1,l,mid,L,mid,v),add(rs[y],rs[x],pos<<1|1,mid+1,r,mid+1,R,v);
}
inline void del(int &y,int x,int pos,int l,int r,int L,int R,int v){
y=++ncnt; int mid=(l+r)>>1;
if (L<=l && r<=R)
{
T[pos].erase(v);
maxv[y]=T[pos].top();
ls[y]=ls[x]; rs[y]=rs[x];
return;
}
maxv[y]=maxv[x];
if (R<=mid)
del(ls[y],ls[x],pos<<1,l,mid,L,R,v),rs[y]=rs[x];
else if (L>mid)
del(rs[y],rs[x],pos<<1|1,mid+1,r,L,R,v),ls[y]=ls[x];
else
del(ls[y],ls[x],pos<<1,l,mid,L,mid,v),del(rs[y],rs[x],pos<<1|1,mid+1,r,mid+1,R,v);
}
inline int query(int x,int t,int l,int r){
if (l==r) return maxv[x];
int mid=(l+r)>>1;
if (t<=mid)
return max(maxv[x],query(ls[x],t,l,mid));
else
return max(maxv[x],query(rs[x],t,mid+1,r));
}
int n,a[N];
int nxt[N],last[N];
int ed[N];
int main()
{
int l,r,lastans,Q;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(Q);
for (int i=1;i<=n;i++) read(a[i]);
for (int i=1;i<=n;i++) last[i]=n+1;
for (int i=n;i;i--) nxt[i]=last[a[i]],last[a[i]]=i;
for (int i=1;i<=n;i++)
if (last[i]!=n+1)
rcnt++,add(root[rcnt],root[rcnt-1],1,1,n,last[i],nxt[last[i]]-1,i);
ed[1]=root[rcnt];
for (int i=1;i<=n;i++)
{
rcnt++,del(root[rcnt],root[rcnt-1],1,1,n,i,nxt[i]-1,a[i]);
if (nxt[i]!=n+1)
rcnt++,add(root[rcnt],root[rcnt-1],1,1,n,nxt[i],nxt[nxt[i]]-1,a[i]);
ed[i+1]=root[rcnt];
}
lastans=0;
while (Q--)
{
read(l); read(r);
l=(l+lastans)%n+1; r=(r+lastans)%n+1; if (l>r) swap(l,r);
lastans=query(ed[l],r,1,n);
printf("%d\n",lastans);
}
return 0;
}