您的位置:首页 > 其它

[BZOJ3489]A simple rmq problem

2018-01-19 11:14 302 查看
转化一下,记$last_i$为$a_i$在数列中上一次出现的位置$+1$,$next_i$为$a_i$在数列中下一次出现的位置$-1$

那么问题转化为,求最大的$a_i$,使得$last_i\leq l$且$next_i\geq r$且$l\leq i\leq r$

上树套树,因为查询$last$是$\leq l$(前缀)所以外层用可持久化线段树,第$i$版本的树存了所有$last_j\leq i$的$a_j$,因为要满足$l\leq i\leq r$所以外层树的下标是数列下标

因为外层可持久化了,所以内层也要可持久化,这里用的是可持久化线段树,为了满足$next_i\geq r$,内层的下标是$next$,值是数列中的数字,内层维护最大值即可

我发现自己又不知道怎么算空间了...

#include<stdio.h>
#include<algorithm>
using namespace std;
struct num{
int las,nex,v,id;
}p[100010];
int a[100010],c[100010],rt[100010],tot1,tot2,n;
struct seg1{
int rt,l,r;
}t1[6000010];
struct seg2{
int l,r,mx;
}t2[40000010];
bool cmp(num a,num b){return a.las<b.las;}
void insert(int nex,int v,int p,int&x,int l,int r){
x=++tot2;
t2[x]=t2[p];
t2[x].mx=max(t2[x].mx,v);
if(l==r)return;
int mid=(l+r)>>1;
if(nex<=mid)
insert(nex,v,t2[p].l,t2[x].l,l,mid);
else
insert(nex,v,t2[p].r,t2[x].r,mid+1,r);
}
void insert(num a,int p,int&x,int l,int r){
x=++tot1;
t1[x]=t1[p];
insert(a.nex,a.v,t1[p].rt,t1[x].rt,1,n);
if(l==r)return;
int mid=(l+r)>>1;
if(a.id<=mid)
insert(a,t1[p].l,t1[x].l,l,mid);
else
insert(a,t1[p].r,t1[x].r,mid+1,r);
}
int query(int nex,int x,int l,int r){
if(x==0)return 0;
if(nex<=l)return t2[x].mx;
int mid=(l+r)>>1;
int ans=query(nex,t2[x].r,mid+1,r);
if(nex<=mid)ans=max(ans,query(nex,t2[x].l,l,mid));
return ans;
}
int query(int L,int R,int x,int l,int r){
if(x==0)return 0;
if(L<=l&&r<=R)return query(R,t1[x].rt,1,n);
int mid=(l+r)>>1,ans=0;
if(L<=mid)ans=max(ans,query(L,R,t1[x].l,l,mid));
if(mid<R)ans=max(ans,query(L,R,t1[x].r,mid+1,r));
return ans;
}
int main(){
int m,i,x,y,las;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",a+i);
for(i=1;i<=n;i++){
p[i].las=c[a[i]]+1;
p[i].v=a[i];
c[a[i]]=i;
p[i].id=i;
}
for(i=1;i<=n;i++)c[i]=n+1;
for(i=n;i>0;i--){
p[i].nex=c[a[i]]-1;
c[a[i]]=i;
}
sort(p+1,p+n+1,cmp);
x=1;
for(i=1;i<=n;i++){
rt[i]=rt[i-1];
while(x<=n&&p[x].las<=i){
insert(p[x],rt[i],rt[i],1,n);
x++;
}
}
las=0;
while(m--){
scanf("%d%d",&x,&y);
x=(x+las)%n+1;
y=(y+las)%n+1;
if(x>y)swap(x,y);
las=query(x,y,rt[x],1,n);
printf("%d\n",las);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: