线段树+二分
#include <iostream>
#include <cstdio>
using namespace std;
int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return f*x;
}
const int N=1e5+5;
int n,m,sig[N*4],tre[N*4],a[N],b[N],c[N],f[N],x,q,ans;
void build(int k,int l,int r,int v)
{
sig[k]=-1;
if(l==r)
{
if(c[l]>=v) tre[k]=1;
else tre[k]=0;
return;
}
int mid=(l+r)/2;
build(k*2,l,mid,v);
build(k*2+1,mid+1,r,v);
tre[k]=tre[k*2]+tre[k*2+1];
}
void update(int k,int l,int r,int v)
{
sig[k]=v;
tre[k]=(r-l+1)*v;
}
void pushdown(int k,int l,int r,int mid)
{
if(sig[k]==-1) return;
update(k*2,l,mid,sig[k]);
update(k*2+1,mid+1,r,sig[k]);
sig[k]=-1;
}
int query(int k,int l,int r,int x,int y)
{
if(l>y||r<x) return 0;
if(l>=x&&r<=y) return tre[k];
int mid=(l+r)/2,sum=0;
pushdown(k,l,r,mid);
sum+=query(k*2,l,mid,x,y);
sum+=query(k*2+1,mid+1,r,x,y);
return sum;
}
void change(int k,int l,int r,int x,int y,int v)
{
if(l>y||r<x) return;
if(l>=x&&r<=y)
{
sig[k]=v;
tre[k]=(r-l+1)*v;
return;
}
int mid=(l+r)/2;
pushdown(k,l,r,mid);
change(k*2,l,mid,x,y,v);
change(k*2+1,mid+1,r,x,y,v);
tre[k]=tre[k*2]+tre[k*2+1];
}
int main()
{
n=read(); m=read();
int l=2147483647,r=-2147483647;
for(int i=1;i<=n;i++) {
c[i]=read();
l=min(l,c[i]); r=max(r,c[i]);
}
for(int i=1;i<=m;i++) {
f[i]=read(); a[i]=read(); b[i]=read();
}
q=read();
while(l<=r)
{
int s=(l+r)/2;
build(1,1,n,s);
for(int i=1;i<=m;i++) {
int sum=query(1,1,n,a[i],b[i]);
if(f[i]==0) {
change(1,1,n,a[i],b[i]-sum,0);
change(1,1,n,b[i]-sum+1,b[i],1);
}
if(f[i]==1) {
change(1,1,n,a[i],a[i]+sum-1,1);
change(1,1,n,a[i]+sum,b[i],0);
}
}
x=query(1,1,n,q,q);
if(x) {
l=s+1;
ans=s;
}
else r=s-1;
}
cout<<ans;
return 0;
}