题目大意:
思路:
观察到操作其实就是将区间内的数字重新排序之后再按照某种方式来排列。模拟的成本显然太高了。考虑二分答案,假设目前答案为x,那么我们把小于等于x的数全部设为0,大于x的数全部设为1,这样整个序列就变成了只有两种数字的序列,每一次操作可以把这一段区间看成三段连续的101来操作。这样我们只需要用线段树来实现区间覆值和区间查询,最后看第k为是比x大还是比x小就好了。时间复杂度 O(nlog2n) O ( n log 2 n )
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define REP(i,a,b) for(int i=a;i<=b;++i)
#define mid ((l+r)>>1)
typedef long long ll;
using namespace std;
void File(){
freopen("coach.in","r",stdin);
freopen("coach.out","w",stdout);
}
const int maxn=5e5+10;
int n,m,k,a[maxn],b[maxn];
int stx[maxn],sty[maxn],top;
struct Segment_Tree{
int val[maxn<<2],tag[maxn<<2];
bool is[maxn<<2];
void pushdown(int rt,int l,int r){
val[rt<<1]=tag[rt]*(mid-l+1); tag[rt<<1]=tag[rt];
val[rt<<1|1]=tag[rt]*(r-mid); tag[rt<<1|1]=tag[rt];
is[rt<<1]=is[rt<<1|1]=true; is[rt]=false;;
}
void build(int rt,int l,int r,int pos){
is[rt]=0;
if(l==r)val[rt]=(a[l]>b[pos]);
else{
build(rt<<1,l,mid,pos);
build(rt<<1|1,mid+1,r,pos);
val[rt]=val[rt<<1]+val[rt<<1|1];
}
}
void update(int rt,int l,int r,int L,int R,int x){
if(L>R)return;
if(L<=l && r<=R){
val[rt]=(r-l+1)*x;
is[rt]=true; tag[rt]=x;
}
else{
if(is[rt])pushdown(rt,l,r);
if(L<=mid)update(rt<<1,l,mid,L,R,x);
if(R>=mid+1)update(rt<<1|1,mid+1,r,L,R,x);
val[rt]=val[rt<<1]+val[rt<<1|1];
}
}
int query(int rt,int l,int r,int L,int R){
if(L<=l && r<=R)return val[rt];
int ret=0;
if(is[rt])pushdown(rt,l,r);
if(L<=mid)ret+=query(rt<<1,l,mid,L,R);
if(R>=mid+1)ret+=query(rt<<1|1,mid+1,r,L,R);
return ret;
}
}T;
bool judge(int pos){
T.build(1,1,n,pos);
REP(i,1,top){
int cnt=T.query(1,1,n,stx[i],sty[i]),L=stx[i]+(cnt+1)/2-1,R=sty[i]-cnt/2+1;
T.update(1,1,n,stx[i],L,1);
T.update(1,1,n,R,sty[i],1);
T.update(1,1,n,L+1,R-1,0);
}
return T.query(1,1,n,k,k)==0;
}
void solve(){
int l=1,r=n;
while(l+1<r){
if(judge(mid))r=mid;
else l=mid+1;
}
if(judge(l))printf("%d",b[l]);
else printf("%d",b[r]);
}
void init(){
scanf("%d%d%d",&n,&m,&k);
REP(i,1,n)scanf("%d",&a[i]);
REP(i,1,n)b[i]=a[i];
sort(b+1,b+n+1);
REP(i,1,m){
int ty,u,v;
scanf("%d",&ty);
if(ty==1){
scanf("%d%d",&u,&v);
++top; stx[top]=u; sty[top]=v;
}
else{
scanf("%d",&u);
top=max(top-u,0);
}
}
}
int main(){
File();
init();
solve();
return 0;
}