[BZOJ3585][清华集训2014]mex 主席树
2017-12-12 20:42
447 查看
考虑用主席树维护到第i个位置时,每个数最后一次出现位置,也就是说维护的是n棵权值线段树,线段树上每个节点表示值域在此之内的每个数最后一次出现位置的最小值。
那么一个询问(l,r)就是在第r棵线段树上查最小的且上一次出现位置小于l的数,经典操作。
注意离散化的时候要把每个值和它+1扔进去离散化,而且要去重,因为不能破坏整数的连续性。
代码:
那么一个询问(l,r)就是在第r棵线段树上查最小的且上一次出现位置小于l的数,经典操作。
注意离散化的时候要把每个值和它+1扔进去离散化,而且要去重,因为不能破坏整数的连续性。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=200010; int a[maxn],z[maxn<<1],n,m; struct tree; tree *NUL; struct tree { int mi; tree *so[2]; tree(){mi=0;so[0]=so[1]=NUL;} void update(){mi=min(so[0]->mi,so[1]->mi);} void build(tree *lst,int p,int l,int r) { if(l==r) {mi=p;return;} int mid=(l+r)>>1;bool b=(a[p]>mid); int lx=b?mid+1:l,rx=b?r:mid; so[b^1]=lst->so[b^1]; (so[b]=new tree)->build(lst->so[b],p,lx,rx); update(); } int query(int p,int l,int r) { if(l==r||this==NUL) return l; int mid=(l+r)>>1; if(so[0]->mi<p) so[0]->query(p,l,mid); else so[1]->query(p,mid+1,r); } }*rt[maxn]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); z[2*i-1]=a[i];z[2*i]=a[i]+1; } sort(z+1,z+2*n+1); int sz; sz=unique(z+1,z+2*n+1)-z-1; for(int i=1; f9a8 i<=n;i++) a[i]=lower_bound(z+1,z+sz+1,a[i])-z; NUL=new tree;NUL->so[0]=NUL->so[1]=NUL; rt[0]=new tree; for(int i=1;i<=n;i++) (rt[i]=new tree)->build(rt[i-1],i,1,sz); while(m--) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",z[rt[r]->query(l,1,sz)]); } return 0; }
相关文章推荐
- 【清华集训2014】mex
- 【XSY1285】【BZOJ3814】【清华集训2014】简单回路 状压DP
- 【BZOJ3812】【UOJ37】【清华集训2014】主旋律
- 【清华集训2014】mex
- 【清华集训2014】mex
- 【清华集训2014】【BZOJ3811】玛里苟斯
- 【清华集训2014】【BZOJ3817】Sum
- 【清华集训2014】【BZOJ3812】主旋律
- 【BZOJ3813】【UOJ38】【清华集训2014】奇数国
- BZOJ 3585: mex [主席树]
- JZOJ 3547【清华集训2014】mex
- bzoj 3816&&uoj #41. [清华集训2014]矩阵变换
- [BZOJ3585]mex 主席树
- 【BZOJ 3585】mex 主席树
- 【清华集训2014】mex
- bzoj 3585: mex && 3339: Rmq Problem -- 主席树
- 【BZOJ3815】【UOJ40】【清华集训2014】卡常数
- BZOJ 3585 mex - 莫队+(分块/树状数组+二分/乱搞/主席树)
- 【BZOJ3811】【UOJ36】【清华集训2014】玛里苟斯
- BZOJ_3585_mex && BZOJ_3339_Rmq Problem_主席树