# TJOI2016&HEOI2016 排序 线段树+二分答案

1:(0,l,r)表示将区间[l,r]的数字升序排序
2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q位置上的数字。

———————————来自YALI省选集训某dalao的试题讨论

//miaomiao 3.10
#include<cstdio>
#include<cstdlib>
#include<algorithm>

using namespace std;

#define For(i, a, b) for(int i = (a); i <= (int)(b); ++i)
#define N (100000+5)

struct OP{
int op, l, r;
}rop[N];

int n, m, r[N], tr[N];

#define lc (o<<1)
#define rc (o<<1|1)
#define mid ((L+R)>>1)

int ql, qr;

struct Seg_tree{
int sum[N<<2], set[N<<2];
bool tag[N<<2];

void maintain(int o, int L, int R){
if(tag[o]){
sum[o] = (R-L+1)*set[o]; return;
}
sum[o] = sum[lc]+sum[rc];
}

void push_down(int o, int L, int R){
if(!tag[o]) return;
tag[o] = 0; tag[lc] = 1; tag[rc] = 1;
set[lc] = set[rc] = set[o];
maintain(lc, L, mid); maintain(rc, mid+1, R);
}

void build(int o, int L, int R){
if(L == R){
sum[o] = tr[L]; tag[o] = false; return;
}

tag[o] = false;
build(lc, L, mid); build(rc, mid+1, R);
maintain(o, L, R);
}

void Modify(int o, int L, int R, int nset){
if(ql <= L && qr >= R){
tag[o] = true; set[o] = nset; maintain(o, L, R);
return;
}

push_down(o, L, R);
if(ql <= mid) Modify(lc, L, mid, nset);
if(qr > mid) Modify(rc, mid+1, R, nset);
maintain(o, L, R);
}

int query(int o, int L, int R){
if(ql <= L && qr >= R) return sum[o];

int ret = 0;
push_down(o, L, R);
if(ql <= mid) ret += query(lc, L, mid);
if(qr > mid) ret += query(rc, mid+1, R);
return ret;
}
}ST;

#undef lc
#undef rc
#undef mid

int Q;

bool check(int now){
For(i, 1, n) tr[i] = r[i]>now;
ST.build(1, 1, n);

int op, Sum1, Sum0, L, R;
For(i, 1, m){
op = rop[i].op; L = ql = rop[i].l; R = qr = rop[i].r;
Sum1 = ST.query(1, 1, n); Sum0 = R-L+1-Sum1;

ql = L; qr = R-(op? Sum0: Sum1);
if(ql <= qr) ST.Modify(1, 1, n, op);
ql = qr+1; qr = R;
if(ql <= qr) ST.Modify(1, 1, n, op^1);
}

ql = qr = Q;
return ST.query(1, 1, n);
}

int main(){
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif

scanf("%d%d", &n, &m);
For(i, 1, n) scanf("%d", &r[i]);
For(i, 1, m) scanf("%d%d%d", &rop[i].op, &rop[i].l, &rop[i].r);

int L = 1, R = n, mid;
scanf("%d", &Q);

while(L < R){
mid = (L+R)>>1;
if(check(mid)) L = mid+1;
else R = mid;
}
printf("%d\n", L);

return 0;
}