bzoj 4552 [Tjoi2016&Heoi2016]排序——二分答案
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4552
二分答案,把 >= mid 的设成1、< mid 的设成0,之后排序就变成区间赋值了。
#include<cstdio> #include<cstring> #include<algorithm> #define ls Ls[cr] #define rs Rs[cr] using namespace std; const int N=1e5+5,M=N<<1; int n,m,a[N],ps; bool b[N]; int tot,Ls[M],Rs[M],sm[M],len[M],tg[M]; struct Node{bool op;int l,r;}q[N]; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } void init(int l,int r,int cr) { len[cr]=r-l+1; if(l==r)return; int mid=l+r>>1; ls=++tot;init(l,mid,ls); rs=++tot;init(mid+1,r,rs); } void build(int l,int r,int cr) { tg[cr]=-1;// if(l==r){sm[cr]=b[l];return;} int mid=l+r>>1; build(l,mid,ls); build(mid+1,r,rs); sm[cr]=sm[ls]+sm[rs]; } void pshd(int cr) { if(tg[cr]<0)return;tg[ls]=tg[rs]=tg[cr]; sm[ls]=(tg[cr]?len[ls]:0);sm[rs]=(tg[cr]?len[rs]:0); tg[cr]=-1; } void mdfy(int l,int r,int cr,int L,int R,bool k) { if(L>R)return;//// if(l>=L&&r<=R){tg[cr]=k;sm[cr]=(k?len[cr]:0);return;} int mid=l+r>>1;pshd(cr); if(L<=mid)mdfy(l,mid,ls,L,R,k); if(mid<R)mdfy(mid+1,r,rs,L,R,k); sm[cr]=sm[ls]+sm[rs]; } int query(int l,int r,int cr,int L,int R) { if(l>=L&&r<=R)return sm[cr]; int mid=l+r>>1; pshd(cr); if(L>mid)return query(mid+1,r,rs,L,R); if(R<=mid)return query(l,mid,ls,L,R); return query(l,mid,ls,L,R)+query(mid+1,r,rs,L,R); } bool chk(int mid) { for(int i=1;i<=n;i++)b[i]=(a[i]>=mid); build(1,n,1); for(int i=1;i<=m;i++) { int d=query(1,n,1,q[i].l,q[i].r); if(q[i].op) { mdfy(1,n,1,q[i].l,q[i].l+d-1,1); mdfy(1,n,1,q[i].l+d,q[i].r,0); } else { mdfy(1,n,1,q[i].r-d+1,q[i].r,1); mdfy(1,n,1,q[i].l,q[i].r-d,0); } } return query(1,n,1,ps,ps); } int main() { n=rdn();m=rdn();tot=1;init(1,n,1); for(int i=1;i<=n;i++)a[i]=rdn(); for(int i=1;i<=m;i++)q[i].op=rdn(),q[i].l=rdn(),q[i].r=rdn(); ps=rdn(); int l=1,r=n,ans; while(l<=r) { int mid=l+r>>1; if(chk(mid))ans=mid,l=mid+1; else r=mid-1; } printf("%d\n",ans); return 0; }