[bzoj3339]mex(线段树)
2017-10-25 20:26
141 查看
题目:
我是超链接题解:
天然巨坑啊线段树维护区间mex值!
在线的话并不怎么会,那可以试试离线啊,把所有询问离线下来按照左端点排序
然后我们考虑l~r和l+1~r的区别,就是l~next[l]-1区间内所有mex比a[l]大的全部改成a[l]
如果把修改的操作想出线段树的话就很简单了吧
要先求出1~i的mex值哦
线段树的叶子节点表示[now,i]这个区间(now是现在左端点的位置,i是查询到的右端点)
线段树中的非叶子节点并没有实际含义,只是为了修改操作的方便。
这种非叶节点没有意义的方法也要学习!代码:
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int N=200005; struct hh{int l,r,id;}q ; int minn[N*4],sg ,a ,last ,nxt ,ans ; bool vis ; int cmp(hh a,hh b){if (a.l==b.l) return a.r<b.r;else return a.l<b.l;} void build(int now,int l,int r) { minn[now]=N; if (l==r){minn[now]=sg[l];return;} int mid=(l+r)>>1; if (l<=mid) build(now<<1,l,mid); if (r>mid) build(now<<1|1,mid+1,r); } void pushdown(int now) { minn[now<<1]=min(minn[now<<1],minn[now]); minn[now<<1|1]=min(minn[now<<1|1],minn[now]); } int ask(int now,int l,int r,int k) { if (minn[now]!=N) pushdown(now); if (l==r) return minn[now]; int mid=(l+r)>>1; if (k<=mid) return ask(now<<1,l,mid,k); else return ask(now<<1|1,mid+1,r,k); } void change(int now,int l,int r,int lrange,int rrange,int k) { if (lrange<=l && rrange>=r) {minn[now]=min(minn[now],k); return;} int mid=(l+r)>>1; if (lrange<=mid) change(now<<1,l,mid,lrange,rrange,k); if (rrange>mid) change(now<<1|1,mid+1,r,lrange,rrange,k); } int main() { int n,Q,i; scanf("%d%d",&n,&Q); for (i=1;i<=n;i++) scanf("%d",&a[i]),last[a[i]]=n+1; int mq=0; for (i=1;i<=n;i++) { vis[a[i]]=1; while (vis[mq]) mq++; sg[i]=mq; } for (i=n;i>=1;i--) nxt[i]=last[a[i]],last[a[i]]=i; build(1,1,n); for (i=1;i<=Q;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+Q+1,cmp); int now=1; for (i=1;i<=Q;i++) { while (now<q[i].l) { change(1,1,n,now,nxt[now]-1,a[now]);//比a[now]大的全都改成a[now] now++; } ans[q[i].id]=ask(1,1,n,q[i].r); } for (i=1;i<=Q;i++) printf("%d\n",ans[i]); }
相关文章推荐
- [bzoj3339]Rmq Problem||[bzoj3585]mex_线段树
- 【BZOJ3339】Rmq Problem【离线】【线段树】【mex】
- hdu 4747 Mex(线段树区间更新+二分)
- Mex(线段树的巧妙应用)
- hdu 4747 Mex 线段树
- HDU 4747 Mex(线段树)
- HDU 4747 Mex (线段树)
- HDU-4747 Mex(线段树区间更新)
- HDU 4747 Mex(线段树)
- hdu-4747-Mex-线段树区域更新
- [BZOJ3339] Rmq Problem&&[BZOJ3585] mex
- HDU 4747 Mex (线段树)
- hdu 4747 Mex (线段树)
- BZOJ 3585: mex( 离线 + 线段树 )
- HDU 4747 Mex (2013杭州网络赛1010题,线段树)
- bzoj3339(线段树)
- hdu - 4747 - Mex(二分+线段树)
- BZOJ3339:Rmq Problem & BZOJ3585 & 洛谷4137:mex——题解
- [BZOJ3339]Rmq Problem(离线+线段树)
- bzoj3339 rmq problem (range mex query)