[BZOJ4552][Tjoi2016&Heoi2016][线段树][二分]排序
来源:互联网 发布:网络常用协议的端口号 编辑:程序博客网 时间:2024/05/20 20:19
题意
求给定序列经过给定排序网络后的第k个元素
鏼爷16年论文小例题%%%
二分答案x,原数列中大于等于x的设为1,小于x的设为0。
每一次排序的区间[l,r]中,有k1个0,k2个1,那么升序就把前k1个覆盖为0,后k2个覆盖为1,降序相反。
可以用线段树维护。
#include <cstdio>#include <iostream>#include <algorithm>#define N 100010using namespace std;int n,m,q;int A[N],B[N];struct stp{ int l,r,op;}s[N];struct lisan{ int x,g; friend bool operator <(lisan a,lisan b){return a.x<b.x;}}L[N];struct sigt{ int l,r,z,o,flg;}T[N<<2];inline void reaD(int &x){ char Ch=getchar();x=0; for(;Ch>'9'||Ch<'0';Ch=getchar()); for(;Ch>='0'&&Ch<='9';x=x*10+Ch-'0',Ch=getchar());}inline void upd(int g){ T[g].z=T[g<<1].z+T[g<<1|1].z; T[g].o=T[g<<1].o+T[g<<1|1].o;}inline void Set(int g,int w){ if(w==1) T[g].z=T[g].r-T[g].l+1,T[g].o=0; else T[g].o=T[g].r-T[g].l+1,T[g].z=0; T[g].flg=w;}inline void pushdown(int g){ if(!T[g].flg) return; Set(g<<1,T[g].flg); Set(g<<1|1,T[g].flg); T[g].flg=0;}void build(int g,int l,int r){ T[g].l=l;T[g].r=r;T[g].flg=0; if(l==r){ if(B[l]) T[g].o=1,T[g].z=0; else T[g].o=0,T[g].z=1; return ; } int mid=l+r>>1; build(g<<1,l,mid); build(g<<1|1,mid+1,r); upd(g);}int query(int g,int l,int r,int w){ if(T[g].l==l&&T[g].r==r) return w==1?T[g].o:T[g].z; pushdown(g); int mid=T[g].l+T[g].r>>1; if(r<=mid) return query(g<<1,l,r,w); if(l>mid) return query(g<<1|1,l,r,w); return query(g<<1,l,mid,w)+query(g<<1|1,mid+1,r,w);}void cover(int g,int l,int r,int w){ if(T[g].l==l&&T[g].r==r){Set(g,w);return;} pushdown(g); int mid=T[g].l+T[g].r>>1; if(r<=mid) cover(g<<1,l,r,w); else if(l>mid) cover(g<<1|1,l,r,w); else cover(g<<1,l,mid,w),cover(g<<1|1,mid+1,r,w); upd(g);}inline bool check(int x){ for(int i=1;i<=n;i++) B[i]=A[i]>=x; build(1,1,n); for(int i=1;i<=m;i++){ int z=query(1,s[i].l,s[i].r,0),o=s[i].r-s[i].l+1-z; if(!z||!o) continue; if(s[i].op) cover(1,s[i].l,s[i].l+o-1,2),cover(1,s[i].r-z+1,s[i].r,1); else cover(1,s[i].r-o+1,s[i].r,2),cover(1,s[i].l,s[i].l+z-1,1); } return query(1,q,q,1);}int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); reaD(n); reaD(m); for(int i=1;i<=n;i++) reaD(A[i]); for(int i=1;i<=m;i++) reaD(s[i].op),reaD(s[i].l),reaD(s[i].r); reaD(q); int l=1,r=n,mid,Ans; while(l<=r) check(mid=l+r>>1)?Ans=mid,l=mid+1:r=mid-1; return printf("%d\n",Ans),0;}
0 0
- [BZOJ4552][Tjoi2016&Heoi2016][线段树][二分]排序
- [bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
- 【bzoj4552】【Tjoi2016】【Heoi2016】【排序】【二分答案】【线段树】
- [BZOJ4552][Tjoi2016&Heoi2016]排序 二分答案+线段树
- 【二分+线段树】BZOJ4552(Tjoi2016&Heoi2016)[排序]题解
- bzoj4552 [ TJOI2016 && HEOI2016 ] -- 二分+线段树
- 【bzoj4552】【Tjoi2016&Heoi2016】【排序】【线段树】
- BZOJ4552: [Tjoi2016&Heoi2016]排序 线段树
- [BZOJ4552][TJOI2016&HEOI2016]排序-线段树合并
- BZOJ4552 [Tjoi2016&Heoi2016]排序
- bzoj4552【TJOI2016&HEOI2016】排序
- 【bzoj4552】 [Tjoi2016&Heoi2016]排序
- [bzoj4552][Tjoi2016&Heoi2016]排序
- bzoj4552: [Tjoi2016&Heoi2016]排序
- [ 线段树套treap ] [ TJOI2016&&HEOI2016 ] BZOJ4552
- TJOI2016&HEOI2016 排序 线段树+二分答案
- bzoj 4552: [Tjoi2016&Heoi2016]排序 二分答案+线段树
- cf 671D Roads in Yusland
- MacOSX上的NFS文件共享
- 第二天、在linux设置Mysql允许用户远程登录
- dijkstra算法
- 嵌入式C++开发详解(五)
- [BZOJ4552][Tjoi2016&Heoi2016][线段树][二分]排序
- BZOJ2073: [POI2004]PRZ
- 利用反射调用私有方法
- Android的一些trick
- (队列思想+快排函数)—keke祝你元宵节快乐!
- 微积分
- IOS开发之OC篇(5)—— NSNumber、NSValue
- oracle笔记整理2
- 解决CentOS无法上网问题