对一个排列进行m次区间内排序操作,给定值q,求位置q上的树
算法:1.首先由于排列所以值域确定(非排列可以采取离散化处理)对值域二分
2.将大于m设为1,其余设为0,得到01序列,对每次(细节)check建立一颗线段树
由区间求和可确定区间内的1的个数,从而完成区间内升序降序排列(01序列特性,总和+排序可确定整个序列,求和线段树可以完成,排序为题设要求)
3.为1二分左端点右移(无m)
为0右端点左移动(包含m)
二分模版!!!
#include<bits/stdc++.h>
using namespace std;
int read() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1e5+50;
struct op{
int type,opl,opr;
}ops[N];
int val[N];
int n,mm,goal,okk=0;
int sum[N<<2],tag[N<<2],bb[N];
void init()
{
n=read();
mm=read();
for(int i=1;i<=n;++i)
bb[i]=read();
for(int i=1;i<=mm;++i)
{
ops[i].type=read();
ops[i].opl=read();
ops[i].opr=read();
}
goal=read();
}
void build(int now,int l,int r)
{
tag[now]=-1;
if(l==r)
{
sum[now]=val[++okk];
return ;
}
int m=(l+r)>>1;
build(now<<1,l,m);
build(now<<1|1,m+1,r);
sum[now]=sum[now<<1]+sum[now<<1|1];
return ;
}
void pushdown(int now,int l,int r)
{
int m=(l+r)>>1;
if(tag[now]!=-1)
{
tag[now<<1]=tag[now<<1|1]=tag[now];
sum[now<<1]=(m-l+1)*tag[now];
sum[now<<1|1]=(r-m)*tag[now];
}
tag[now]=-1;
return ;
}
void update(int now ,int l,int r,int x,int y,int v)
{
if(x<=l&&r<=y)
{
tag[now]=v;
sum[now]=v*(r-l+1);
return ;
}
pushdown(now,l,r);
int m=(l+r)>>1;
if(x<=m)
update(now<<1,l,m,x,y,v);
if(y>m)
update(now<<1|1,m+1,r,x,y,v);
sum[now]=sum[now<<1]+sum[now<<1|1];
return ;
}
int queryy(int now,int l ,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return sum[now];
}
pushdown(now,l,r);
int t1=0,t2=0;
int m=(l+r)>>1;
if(x<=m)
t1=queryy(now<<1,l,m,x,y);
if(y>m)
t2=queryy(now<<1|1,m+1,r,x,y);
sum[now]=sum[now<<1]+sum[now<<1|1];
return t1+t2;
}
bool check(int x)
{
int kk;
for(int i=1;i<=n;++i)
{
val[i]=(bb[i]>x)?1:0;
}
build(1,1,n);
for(int i=1;i<=mm;++i)
{
op aa=ops[i];
kk=queryy(1,1,n,aa.opl,aa.opr);
kk=(aa.opr-aa.opl+1)-kk;
if(aa.type==0)
{
if(kk>0)
{
update(1,1,n,aa.opl,aa.opl+kk-1,0);
}
if(kk<aa.opr-aa.opl+1)
{
update(1,1,n,aa.opl+kk,aa.opr,1);
}
}
else {
if(kk>0)
{
update(1,1,n,aa.opr-kk+1,aa.opr,0);
}
if(kk<aa.opr-aa.opl+1)
{
update(1,1,n,aa.opl,aa.opr-kk,1);
}
}
}
return queryy(1,1,n,goal,goal)==1;
}
int main ()
{
init();
int ll=1,rr=n,mid,ans;
while(ll<rr)
{
mid=(ll+rr)>>1;
if(check(mid))
{
ll=mid+1;
}
else {
rr=mid;
}
okk=0;
}
write(ll);
return 0;
}