題意:
給定一個數列{
解題報告:
不會樹套樹,只能膜線段樹題解
二分最終的答案
那麼每次驗證的時候我們只要得出最後的01序列然後看第
這具有單調性所以可以二分
怎麼得到最終數列呢?對於上述我們的驗證方法,所有0之間與所有1之間是沒有區別的
所以每次排序我們只要按照操作將0放在區間的一邊,將1放在另一邊,這可以用線段樹輕鬆解決
可以將有序的數據轉化爲無序的來簡化問題
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
#define ls (x<<1)
#define rs (x<<1|1)
#define mid (l+r>>1)
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
int a=0;char f=1,c=nc();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
while(c>='0'&&c<='9'){a=a*10+c-'0';c=nc();}
return a*f;
}
struct xw{
int opt,l,r;
}q[N];
int n,m,pos,a[N],sum[N<<2],lzy[N<<2];
void update(int x,int l,int r){if(l!=r) sum[x]=sum[ls]+sum[rs];}
void build(int x,int l,int r,int v){
lzy[x]=-1;
if(l==r){
sum[x]=(a[l]>=v);
return;
}
build(ls,l,mid,v),build(rs,mid+1,r,v);
update(x,l,r);
return;
}
void push(int x,int l,int r){
if(l==r) return;
if(lzy[x]!=-1){
int t=lzy[x];lzy[x]=-1;
sum[ls]=(mid-l+1)*t,sum[rs]=(r-mid)*t,lzy[ls]=lzy[rs]=t;
}
}
int query(int x,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return sum[x];
push(x,l,r);
int res=0;
if(ql<=mid) res+=query(ls,l,mid,ql,qr);
if(qr>mid) res+=query(rs,mid+1,r,ql,qr);
update(x,l,r);
return res;
}
void change(int x,int l,int r,int ql,int qr,int v){
if(l>=ql&&r<=qr){
sum[x]=(r-l+1)*v;
lzy[x]=v;
return;
}
push(x,l,r);
if(ql<=mid) change(ls,l,mid,ql,qr,v);
if(qr>mid) change(rs,mid+1,r,ql,qr,v);
update(x,l,r);
return;
}
void print(){for(int i=1;i<=n;++i) printf("%d%s",query(1,1,n,i,i),i==n?"\n":" ");}
bool check(int x){
build(1,1,n,x);
// print();
for(int i=1;i<=m;++i){
int num1=query(1,1,n,q[i].l,q[i].r);
int num0=q[i].r-q[i].l+1-num1;
if(!q[i].opt){
if(num0) change(1,1,n,q[i].l,q[i].l+num0-1,0);
if(num1) change(1,1,n,q[i].r-num1+1,q[i].r,1);
}
else{
if(num1) change(1,1,n,q[i].l,q[i].l+num1-1,1);
if(num0) change(1,1,n,q[i].r-num0+1,q[i].r,0);
}
}
// print();
return query(1,1,n,pos,pos);
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1;i<=m;++i) q[i].opt=read(),q[i].l=read(),q[i].r=read();
int l=1,r=n,ans=N;
pos=read();
while(l<=r){
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
}