# BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*

6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3

### Sample Output

5

#include<bits/stdc++.h>
using namespace std;
#define fu(a,b,c) for(int a=b;a<=c;++a)
#define N 100010
#define LD (t<<1)
#define RD (t<<1|1)
int a[N],b[N],n,m,k;
int l[N],r[N],typ[N];
int siz[N<<2],chg[N<<2];
void pushup(int t){siz[t]=siz[LD]+siz[RD];}
void pushdown(int t,int l,int r){
if(l==r)return;
if(chg[t]!=-1){
int mid=(l+r)>>1;
if(l<=mid)chg[LD]=chg[t],siz[LD]=(mid-l+1)*chg[t];
if(mid<r)chg[RD]=chg[t],siz[RD]=(r-mid)*chg[t];
chg[t]=-1;
}
}
void build(int t,int l,int r){
if(l>r)return;
chg[t]=-1;
if(l==r){siz[t]=b[l];return;}
int mid=(l+r)>>1;
build(LD,l,mid);
build(RD,mid+1,r);
pushup(t);
}
void modify(int t,int l,int r,int L,int R,int vl){
if(L>R)return;
if(L<=l&&r<=R){chg[t]=vl,siz[t]=(r-l+1)*vl;return;}
pushdown(t,l,r);
int mid=(l+r)>>1;
if(R<=mid)modify(LD,l,mid,L,R,vl);
else if(L>mid)modify(RD,mid+1,r,L,R,vl);
else modify(LD,l,mid,L,mid,vl),modify(RD,mid+1,r,mid+1,R,vl);
pushup(t);
}
int query(int t,int l,int r,int L,int R){
if(L<=l&&r<=R)return siz[t];
pushdown(t,l,r);
int mid=(l+r)>>1,ans=0;
if(R<=mid)ans=query(LD,l,mid,L,R);
else if(L>mid)ans=query(RD,mid+1,r,L,R);
else ans=query(LD,l,mid,L,mid)+query(RD,mid+1,r,mid+1,R);
pushup(t);
return ans;
}
bool check(int val){
fu(i,1,n)b[i]=(a[i]>=val);
build(1,1,n);
fu(i,1,m){
int s=query(1,1,n,l[i],r[i]);
if(typ[i]==0){
modify(1,1,n,l[i],r[i]-s,0);
modify(1,1,n,r[i]-s+1,r[i],1);
}else{
modify(1,1,n,l[i],l[i]+s-1,1);
modify(1,1,n,l[i]+s,r[i],0);
}
}
return query(1,1,n,k,k);
}
int main(){
scanf("%d%d",&n,&m);
fu(i,1,n)scanf("%d",&a[i]);
fu(i,1,m)scanf("%d%d%d",&typ[i],&l[i],&r[i]);
scanf("%d",&k);
int l=1,r=n,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d",ans);
return 0;
}

posted @ 2018-09-19 18:59  Dream_maker_yk  阅读(108)  评论(0编辑  收藏  举报