BC#76原题……
二分答案,把小于等于mid的设成零,大于mid的设成1,然后排序可视为区间赋值和区间求和,可用线段树做
当mid大于等于答案的时候,最后p的位置一定是0,当mid小于答案的时候,p的位置一定是1,所以满足可二分性
复杂度O(n log^2 n)
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
using namespace std;
#define MAXN 100010
#define MAXM 1010
#define ll long long
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
int n,m;
int a[MAXN];
bool c[MAXN];
int L[MAXN],R[MAXN];
int s[MAXN*4],ch[MAXN*4];
int p;
inline void ud(int x){
s[x]=s[x<<1]+s[x<<1|1];
}
inline void toch(int x,int y,int z,int cv){
ch[x]=cv;
s[x]=(z-y+1)*cv;
}
inline void pd(int x,int y,int z){
if(ch[x]!=-1){
int mid=y+z>>1;
toch(x<<1,y,mid,ch[x]);
toch(x<<1|1,mid+1,z,ch[x]);
ch[x]=-1;
}
}
void build(int x,int y,int z,int l){
ch[x]=-1;
if(y==z){
if(a[y]<=l){
s[x]=0;
}else{
s[x]=1;
}
return ;
}
int mid=y+z>>1;
build(x<<1,y,mid,l);
build(x<<1|1,mid+1,z,l);
ud(x);
}
int ask(int x,int y,int z,int l,int r){
if(y==l&&z==r){
return s[x];
}
pd(x,y,z);
int mid=y+z>>1;
if(r<=mid){
return ask(x<<1,y,mid,l,r);
}else if(l>mid){
return ask(x<<1|1,mid+1,z,l,r);
}else{
return ask(x<<1,y,mid,l,mid)+ask(x<<1|1,mid+1,z,mid+1,r);
}
}
void change(int x,int y,int z,int l,int r,int cv){
if(l>r){
return ;
}
if(y==l&&z==r){
toch(x,y,z,cv);
return ;
}
pd(x,y,z);
int mid=y+z>>1;
if(r<=mid){
change(x<<1,y,mid,l,r,cv);
}else if(l>mid){
change(x<<1|1,mid+1,z,l,r,cv);
}else{
change(x<<1,y,mid,l,mid,cv);
change(x<<1|1,mid+1,z,mid+1,r,cv);
}
ud(x);
}
bool OK(int x){
int i;
build(1,1,n,x);
for(i=1;i<=m;i++){
int t=ask(1,1,n,L[i],R[i]);
if(!c[i]){
change(1,1,n,L[i],R[i]-t,0);
change(1,1,n,R[i]-t+1,R[i],1);
}else{
change(1,1,n,L[i],L[i]+t-1,1);
change(1,1,n,L[i]+t,R[i],0);
}
}
return !ask(1,1,n,p,p);
}
int main(){
int i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(i=1;i<=m;i++){
scanf("%d%d%d",&c[i],&L[i],&R[i]);
}
scanf("%d",&p);
int l=1,r=n;
int ans;
while(l<=r){
int mid=l+r>>1;
if(OK(mid)){
ans=mid;
r=mid-1;
}else{
l=mid+1;
}
}
printf("%d\n",ans);
return 0;
}
/*
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
*/