[BZOJ] 4552: [Tjoi2016&Heoi2016]排序
阿新 • • 發佈:2018-11-02
通過各種手段把序列問題變成01序列問題可以簡化問題
這裡可以用二分答案,把大於等於的變成1,小於的變成0
然後區間排序就是線段樹區間賦值操作啦
複雜度\(O(nlog^2n)\)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c=='-'?-1:1; while(isdigit(c))ret=ret*10+c-'0',c=getchar(); return ret*f; } #define pc putchar #define space() pc(' ') #define nextline() pc('\n') void pot(int x){if(!x)return;pot(x/10);pc('0'+x%10);} void out(int x){if(!x)pc('0');if(x<0)pc('-'),x=-x;pot(x);} #define ls (cur<<1) #define rs (cur<<1|1) #define mid (((l)+(r))>>1) const int MAXN = 100005; int val[MAXN<<2],tag[MAXN<<2]; int n,m; int a[MAXN]; int M; void pushdown(int cur,int l,int r){ if(tag[cur]==-1) return; if(l==r) return; val[ls]=(mid-l+1)*tag[cur]; val[rs]=(r-mid)*tag[cur]; tag[ls]=tag[cur]; tag[rs]=tag[cur]; tag[cur]=-1; } void pushup(int cur){val[cur]=val[ls]+val[rs];} void build(int cur,int l,int r){ if(l==r){val[cur]=(a[l]>=M);return;} build(ls,l,mid);build(rs,mid+1,r); pushup(cur); } void update(int L,int R,int cur,int l,int r,int w){ if(L>R) return; if(L<=l&&r<=R){tag[cur]=w;val[cur]=w*(r-l+1);return;} pushdown(cur,l,r); if(L<=mid) update(L,R,ls,l,mid,w); if(mid <R) update(L,R,rs,mid+1,r,w); pushup(cur); } int query1(int L,int R,int cur,int l,int r){ if(L<=l&&r<=R){return val[cur];} pushdown(cur,l,r); int ret=0; if(L<=mid) ret+=query1(L,R,ls,l,mid); if(mid <R) ret+=query1(L,R,rs,mid+1,r); return ret; } struct Qry{ int op,x,y; Qry(int _x=0,int _y=0,int _z=0){op=_x;x=_y;y=_z;} }qry[MAXN]; void clear(){ memset(tag,-1,sizeof(tag)); memset(val,0,sizeof(val)); } int p; bool check(){ clear(); build(1,1,n); for(int i=1;i<=m;i++){ int x=qry[i].x,y=qry[i].y; if(qry[i].op==1){ int tmp=query1(x,y,1,1,n); update(x,x+tmp-1,1,1,n,1); update(x+tmp,y,1,1,n,0); }else{ int tmp=y-x+1-query1(x,y,1,1,n); update(x,x+tmp-1,1,1,n,0); update(x+tmp,y,1,1,n,1); } } return query1(p,p,1,1,n); } int main(){ n=rd();m=rd(); for(int i=1;i<=n;i++) a[i]=rd(); int tp,x,y; for(int i=1;i<=m;i++){ tp=rd();x=rd();y=rd(); qry[i]=Qry(tp,x,y); } p=rd(); int l=1,r=n,ans=0; while(l<=r){ M=(l+r)>>1; if(check()) l=M+1,ans=M; else r=M-1; } cout<<ans; return 0; }