# bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树）

#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1
const int M = 1e5 +10;
int sum[M<<2],flag[M<<2],lazy[M<<2],a[M],b[M],op[M];
struct node{
int l,r;
}q[M];

void pushup(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void pushdown(int l,int r,int rt){
if(flag[rt]){
mid;
sum[rt<<1] = lazy[rt]*(m-l+1);
sum[rt<<1|1] = lazy[rt]*(r-m);
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
flag[rt<<1] = flag[rt<<1|1] = flag[rt];
flag[rt] = 0;
}
}

void build(int l,int r,int rt){
flag[rt] = 0; lazy[rt] = 0;
if(l == r){
sum[rt] = b[l];
return;
}
mid;
build(lson); build(rson);
pushup(rt);
}

void update(int L,int R,int c,int l,int r,int rt){
if(L <= l&&R >= r){
sum[rt] = c*(r-l+1);
lazy[rt] = c; flag[rt] = 1;
return ;
}
pushdown(l,r,rt);
mid;
if(L <= m) update(L,R,c,lson);
if(R > m) update(L,R,c,rson);
pushup(rt);
}

int query(int L,int R,int l,int r,int rt){
if(L <= l&&R >= r){
return sum[rt];
}
pushdown(l,r,rt);
mid;
int ret = 0;
if(L <= m) ret += query(L,R,lson);
if(R > m) ret += query(L,R,rson);
return ret ;
}

int main()
{
int n,k,pos;
scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i ++)
scanf("%d",&a[i]);
for(int i = 1;i <= k;i ++)
scanf("%d%d%d",&op[i],&q[i].l,&q[i].r);
scanf("%d",&pos);
int l = 1,r = n;
while(l < r){
mid;
for(int i = 1;i <= n;i ++){
if(a[i] > m) b[i] = 1;
else b[i] = 0;
}
build(1,n,1);
for(int i = 1;i <= k;i ++){
int cnt = query(q[i].l,q[i].r,1,n,1);
if(op[i]){  //降序排列，1放在前面，0放在后面
if(cnt) update(q[i].l,q[i].l+cnt-1,1,1,n,1);
if(cnt+q[i].l <= q[i].r) update(q[i].l+cnt,q[i].r,0,1,n,1);
}
else{  //升序排序，1放在后面，0放在前面
if(cnt) update(q[i].r-cnt+1,q[i].r,1,1,n,1);
if(q[i].r-cnt >= q[i].l) update(q[i].l,q[i].r-cnt,0,1,n,1);
}
}
if(query(pos,pos,1,n,1)) l = m+1;
else r = m;
}
printf("%d\n",l);
return 0;
}

posted @ 2018-09-02 18:10  冥想选手  阅读(159)  评论(0编辑  收藏  举报