/*
题目描述
在 20162016 年,佳媛姐姐喜欢上了数字序列。因而她经常研究关于序列的一些奇奇怪怪的问题,现在她在研究一个难题,需要你来帮助她。
这个难题是这样子的:给出一个 1 到 n 的排列,现在对这个排列序列进行 m 次局部排序,排序分为两种:
0 l r 表示将区间 [l,r][l,r] 的数字升序排序
1 l r 表示将区间 [l,r][l,r] 的数字降序排序
注意,这里是对下标在区间 [l,r][l,r] 内的数排序。
最后询问第 q 位置上的数字。
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
ac 5
*/
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e6 + 10;
static int L[maxn], R[maxn], op[maxn];
static int n, m, k;
struct node
{
int l, r;
int sum, tag;//tag:区间标记为0或者为1
};
struct sgt_tree
{
node t[maxn * 49];
int a[maxn];
void pushup(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
}
void build(int u, int l, int r, int z)
{
t[u].l = l, t[u].r = r, t[u].tag = -1;
if (l == r)
{
t[u].sum = (a[l] >= z);
return;
}
int mid = (l + r) / 2;
build(u << 1, l, mid, z);
build(u << 1 | 1, mid + 1, r, z);
pushup(u); t[u].tag = -1;
}
void pushdown(int u)
{
if (t[u].tag != -1)
{
auto& tt = t[u], & ll = t[u << 1], & rr = t[u << 1 | 1];
ll.tag = rr.tag = tt.tag;
ll.sum = (ll.r - ll.l + 1) * tt.tag;
rr.sum = (rr.r - rr.l + 1) * tt.tag;
tt.tag = -1;
}
}
int sum(int u, int ql, int qr)
{
if (t[u].l > qr || t[u].r < ql)return 0;
if (ql <= t[u].l && t[u].r <= qr)return t[u].sum;
pushdown(u);
return sum(u << 1, ql, qr) + sum(u << 1 | 1, ql, qr);
}
void update(int u, int ql, int qr, int v)
{
if (t[u].l > qr || t[u].r < ql)return;
if (ql <= t[u].l && t[u].r <= qr)
{
t[u].sum = (t[u].r - t[u].l + 1) * v;
t[u].tag = v;
return;
}
pushdown(u);
update(u << 1, ql, qr, v); update(u << 1 | 1, ql, qr, v);
pushup(u);
}
int ask(int u, int p)
{
if (t[u].l == t[u].r)return t[u].sum;
int mid = (t[u].l + t[u].r) >> 1;
pushdown(u);
if (p <= mid)return ask(u << 1, p);
else return ask(u << 1 | 1, p);
}
}sgt;
inline int read()
{
char ch = getchar(); int x = 0;
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
return x;
}
bool cek(int rs)
{
sgt.build(1, 1, n, rs);
for (int i = 1; i <= m; i++)
{
int z = sgt.sum(1, L[i], R[i]);
if (op[i] == 0)//升序
{
sgt.update(1, R[i] - z + 1, R[i], 1);
sgt.update(1, L[i], R[i] - z, 0);
}
else
{
sgt.update(1, L[i], L[i] + z - 1, 1);
sgt.update(1, L[i] + z, R[i], 0);
}
}
return sgt.ask(1, k);
}
int main()
{
n = read(); m = read();
for (int i = 1; i <= n; i++)sgt.a[i] = read();
for (int i = 1; i <= m; i++) {
op[i] = read(); L[i] = read(); R[i] = read();
}
k = read();
int l = 1, r = n, ans = -1;
while (l <= r)
{
int mid = (l + r) / 2;
if (cek(mid))l = mid + 1, ans = mid;
else r = mid - 1;
}
printf("%d\n", ans);
return 0;
}