[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$,值是数列中的数字,内层维护最大值即可
我发现自己又不知道怎么算空间了...
那么问题转化为,求最大的$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); } }
相关文章推荐
- bzoj3489 A simple rmq problem
- [BZOJ]3489 A simple rmq problem 主席树套树
- [BZOJ 3489]A simple rmq problem
- 【BZOJ3489】A simple rmq problem
- BZOJ 3489 A simple rmq problem ——KD-Tree
- BZOJ 3489: A simple rmq problem 树套树
- BZOJ3489 A simple rmq problem
- 【bzoj3489】 A simple rmq problem
- bzoj 3489: A simple rmq problem
- BZOJ 3489 A simple rmq problem
- bzoj 3489 A simple rmq problem - 线段树
- BZOJ 3489 A simple rmq problem
- 【31.94%】【BZOJ 3489】A simple rmq problem
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
- BZOJ 3489: A simple rmq problem
- BZOJ_3489_ A simple rmq problem_KDTree
- bzoj3489 A simple rmq problem
- bzoj3489 A simple rmq problem(K-D tree三维子空间求最大值)
- BZOJ 3489 A simple rmq problem 可持久化树套树
- bzoj3489 A simple rmq problem 可持久化树套树