要开O2才能过T_T
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=2147483647;
const int maxn=5e4+5;
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int n,m,a[maxn];
int rt[maxn*25],tot=0;
namespace SP {
int ch[maxn*25][2],val[maxn*25],cnt[maxn*25],par[maxn*25],sz[maxn*25];
il void pushup(int x) {
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];
}
il bool ws(int x) {
return ch[par[x]][1]==x;
}
il void rotate(int x) {
int f=par[x],ff=par[f],k=ws(x),w=ch[x][k^1];
ch[f][k]=w,par[w]=f;
ch[ff][ws(f)]=x,par[x]=ff;
ch[x][k^1]=f,par[f]=x;
pushup(f),pushup(x);
}
il void splay(int i,int x,int goal=0) {
while(par[x]!=goal) {
int f=par[x],ff=par[f];
if(ff!=goal) {
if(ws(x)==ws(f)) rotate(f);
else rotate(x);
}
rotate(x);
}
if(!goal) rt[i]=x;
}
il void Find(int i,int x) {
int cur=rt[i];
while(ch[cur][x>val[cur]] && x!=val[cur]) {
cur=ch[cur][x>val[cur]];
}
splay(i,cur);
}
il void Insert(int i,int x) {
int cur=rt[i],p=0;
if(rt[i]==0) {
cur=rt[i]=++tot;
val[cur]=x,sz[cur]=cnt[cur]=1;
ch[cur][1]=ch[cur][0]=0,par[cur]=0;
return ;
}
while(cur && val[cur]!=x) {
p=cur;
cur=ch[cur][x>val[cur]];
}
if(cur) cnt[cur]++;
else {
cur=++tot;
if(p) ch[p][x>val[p]]=cur;
ch[cur][0]=ch[cur][1]=0;
par[cur]=p,val[cur]=x;
cnt[cur]=sz[cur]=1;
}
splay(i,cur);
}
il int Rank(int i,int x) {
Find(i,x);
return sz[ch[rt[i]][0]]+(val[rt[i]]<x?cnt[rt[i]]:0);
}
il int Pre(int i,int x) {
Find(i,x);
if(val[rt[i]]<x) return rt[i];
int cur=ch[rt[i]][0];
while(ch[cur][1]) cur=ch[cur][1];
return cur;
}
il int Back(int i,int x) {
Find(i,x);
if(val[rt[i]]>x) return rt[i];
int cur=ch[rt[i]][1];
while(ch[cur][0]) cur=ch[cur][0];
return cur;
}
il int Prenum(int i,int x) {
return val[Pre(i,x)];
}
il int Backnum(int i,int x) {
return val[Back(i,x)];
}
il void Remove(int i,int x) {
int last=Pre(i,x),beh=Back(i,x);
splay(i,last),splay(i,beh,last);
int del=ch[beh][0];
if(cnt[del]>1) {
cnt[del]--;
splay(i,del);
}
else ch[beh][0]=0;
}
}
namespace Seg {
il void spbuild(int l,int r,int nrt) {
SP::Insert(nrt,-inf),SP::Insert(nrt,inf);
for(int i=l; i<=r; ++i) SP::Insert(nrt,a[i]);
}
il void build(int l,int r,int nrt) {
spbuild(l,r,nrt);
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,nrt<<1);
build(mid+1,r,nrt<<1|1);
}
il void update(int l,int r,int x,int C,int nrt) {
SP::Remove(nrt,a[x]);
SP::Insert(nrt,C);
if(l==r) return;
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,C,nrt<<1);
else update(mid+1,r,x,C,nrt<<1|1);
}
il int qRank(int L,int R,int l,int r,int nrt,int k){
if(L<=l && R>=r) return SP::Rank(nrt,k)-1;
int mid=(l+r)>>1,num=0;
if(L<=mid) num+=qRank(L,R,l,mid,nrt<<1,k);
if(R>mid) num+=qRank(L,R,mid+1,r,nrt<<1|1,k);
return num;
}
il int qRank(int L,int R,int k){
return qRank(L,R,1,n,1,k)+1;
}
il int qPre_Back(int L,int R,int l,int r,int nrt,int k,bool fg){
// fg==1?Pre:Back
int ans=fg?-inf:inf;
if(L<=l && R>=r){
fg?(ans=max(ans,SP::Prenum(nrt,k))):(ans=min(ans,SP::Backnum(nrt,k)));
return ans;
}
int mid=(l+r)>>1;
if(L<=mid){
if(fg) ans=max(ans,qPre_Back(L,R,l,mid,nrt<<1,k,fg));
else ans=min(ans,qPre_Back(L,R,l,mid,nrt<<1,k,fg));
}
if(R>mid){
if(fg) ans=max(ans,qPre_Back(L,R,mid+1,r,nrt<<1|1,k,fg));
else ans=min(ans,qPre_Back(L,R,mid+1,r,nrt<<1|1,k,fg));
}
return ans;
}
}
il int getKth(int L,int R,int k){
int le=0,ri=1e8,ans=0,mid;
while(le<=ri){
mid=(le+ri)>>1;
if(Seg::qRank(L,R,mid)<=k) ans=mid,le=mid+1;
else ri=mid-1;
}
return ans;
}
int main() {
// std::ios::sync_with_stdio(0);cin.tie(0);
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i) scanf("%d",&a[i]);
Seg::build(1,n,1);
int op,x,y,z;
for(int i=1; i<=m; ++i) {
scanf("%d%d%d",&op,&x,&y);
if(op==3) Seg::update(1,n,x,y,1),a[x]=y;
else {
scanf("%d",&z);
if(op==1) printf("%d\n",Seg::qRank(x,y,z));
if(op==2) printf("%d\n",getKth(x,y,z));
if(op==4) printf("%d\n",Seg::qPre_Back(x,y,1,n,1,z,1));
if(op==5) printf("%d\n",Seg::qPre_Back(x,y,1,n,1,z,0));
}
}
return 0;
}