bzoj 3489 A simple rmq problem —— 主席树套线段树

时间:2021-12-08 12:45:58

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489

题解:http://www.itdaan.com/blog/2017/11/24/9bc46b690756fe252e17fc3ca90aa01.html

在我挣扎一下午时 Narh 早就A了...

于是看看有何不同,发现 add  和 insert 中必须把 ls[x] = ls[y] , rs[x] = rs[y] 写在前面,而不能是修改 rs 则在那里单写一个 ls[x] = ls[y] 什么的,否则过不了样例...

然后 find 和 query 中一定要有一个 if(!x) return 0; ,否则秒 WA ...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
int const xn=1e5+,xm=xn*,xy=xm*;
int n,m,cnt,rt[xn],ls[xm],rs[xm],cnt2,rt2[xm],ls2[xy],rs2[xy],lst[xn],mx[xy];
struct N{int pr,nxt,pos,val;}p[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
bool cmp(N x,N y){return x.pr<y.pr;}
void add(int &x,int y,int l,int r,N t)
{
x=++cnt2;
ls2[x]=ls2[y]; rs2[x]=rs2[y];
mx[x]=max(mx[y],t.val);
if(l==r)return;
if(t.pos<=mid)add(ls2[x],ls2[y],l,mid,t);
else add(rs2[x],rs2[x],mid+,r,t);
}
void insert(int &x,int y,int l,int r,N t)
{
x=++cnt;
ls[x]=ls[y]; rs[x]=rs[y];
add(rt2[x],rt2[y],,n+,t);//!!!
if(l==r)return;
if(t.nxt<=mid)insert(ls[x],ls[y],l,mid,t);
else insert(rs[x],rs[y],mid+,r,t);
}
int find(int x,int l,int r,int L,int R)
{
if(!x)return ;//!!
if(l>=L&&r<=R)return mx[x];
int ret=;
if(mid>=L)ret=max(ret,find(ls2[x],l,mid,L,R));
if(mid<R)ret=max(ret,find(rs2[x],mid+,r,L,R));
return ret;
}
int query(int x,int l,int r,int L,int R,int ql,int qr)
{
if(!x)return ;//!!
if(l>=L&&r<=R)return find(rt2[x],,n+,ql,qr);
int ret=;
if(mid>=L)ret=max(ret,query(ls[x],l,mid,L,R,ql,qr));
if(mid<R)ret=max(ret,query(rs[x],mid+,r,L,R,ql,qr));
return ret;
}
int main()
{
n=rd(); m=rd();
for(int i=,x;i<=n;i++)
{
x=rd();
p[i].pos=i; p[i].val=x;
p[i].pr=lst[x]; p[lst[x]].nxt=i;
lst[x]=i;
}
for(int i=;i<=n;i++)if(!p[i].nxt)p[i].nxt=n+;
sort(p+,p+n+,cmp); for(int i=,t=;i<=n+;i++)
{
rt[i]=rt[i-];
while(p[t].pr==i&&t<=n)insert(rt[i],rt[i],,n+,p[t++]);
}
for(int i=,x,y,l,r,lt=;i<=m;i++)
{
x=rd(); y=rd();
l=min((x+lt)%n+,(y+lt)%n+);
r=max((x+lt)%n+,(y+lt)%n+);
lt=query(rt[l-],,n+,r+,n+,l,r);//
printf("%d\n",lt);
}
return ;
}