[BZOJ] 4552: [Tjoi2016&Heoi2016]排序
通过各种手段把序列问题变成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;
}
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9898840.html