#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<stack> #include<vector> #define Tp Treap* #define DTp pair<Tp,Tp> #define ft first #define sc second #define MAXN 50000+10 #define INF 2147483647 using namespace std; struct SBT{ struct Treap{ Tp l;Tp r; int key,size,fix; }; Tp root; int Size(Tp A){ return (A?A->size:0); } void upd(Tp A){ A->size=Size(A->l)+Size(A->r)+1; } void Print(Tp A,int k){ if(!A)return; Print(A->l,k+1); printf("%d,",A->key); Print(A->r,k+1); if(!k)printf(" "); } Tp new_treap(int v){ Tp ret;ret=new Treap(); ret->l=ret->r=NULL; ret->key=v,ret->size=1,ret->fix=rand(); return ret; } Tp Build(int a[],int L,int R){ vector<int> b; stack<Tp> s; Tp lst; for(int i=L;i<=R;i++)b.push_back(a[i]); sort(b.begin(),b.end()); for(int i=0;i<b.size();i++){ Tp x=new_treap(b[i]); lst=NULL; while(!s.empty()&&s.top()->fix>x->fix){ upd(s.top()); lst=s.top(); s.pop(); } if(!s.empty()) s.top()->r=x; x->l=lst; s.push(x); } while(!s.empty()){ upd(s.top()); lst=s.top(); s.pop(); } return lst; } Tp Merge(Tp A,Tp B){ if(!A)return B; if(!B)return A; if(A->fix<B->fix){ A->r=Merge(A->r,B); upd(A); return A; } else{ B->l=Merge(A,B->l); upd(B); return B; } } DTp Split(Tp A,int k){ if(!A)return DTp(NULL,NULL); DTp y; if(Size(A->l)>=k){ y=Split(A->l,k); A->l=y.sc; upd(A); y.sc=A; } else{ y=Split(A->r,k-Size(A->l)-1); A->r=y.ft; upd(A); y.ft=A; } return y; } int GetKth(Tp A,int v){ if(!A)return 0; return (v<=A->key?GetKth(A->l,v):GetKth(A->r,v)+Size(A->l)+1); } int Pre(int v){ int k=GetKth(root,v); if(!k)return -INF; //!!! DTp x=Split(root,k-1); DTp y=Split(x.sc,1); int ans=(y.ft?y.ft->key:-INF); root=Merge(x.ft,Merge(y.ft,y.sc)); return ans; } int Nxt(int v){ int k=GetKth(root,v+1); DTp x=Split(root,k); DTp y=Split(x.sc,1); int ans=(y.ft?y.ft->key:INF); root=Merge(x.ft,Merge(y.ft,y.sc)); return ans; } void Delete(int v){ int k=GetKth(root,v); DTp x=Split(root,k); DTp y=Split(x.sc,1); root=Merge(x.ft,y.sc); } void Insert(int v){ int k=GetKth(root,v); DTp x=Split(root,k); Tp t=new_treap(v); root=Merge(x.ft,Merge(t,x.sc)); } }dat[MAXN<<2]; int a[MAXN]; int n,m; void build(int k,int L,int R){ dat[k].root=dat[k].Build(a,L,R-1); if(L+1==R)return; build(k<<1,L,(L+R)>>1); build(k<<1|1,(L+R)>>1,R); } int rk(int a,int b,int k,int L,int R,int x){// ret=ans-1 int mid=(L+R)>>1; if(a<=L&&R<=b)return dat[k].GetKth(dat[k].root,x); if(b<=mid)return rk(a,b,k<<1,L,mid,x); if(a>=mid)return rk(a,b,k<<1|1,mid,R,x); return rk(a,b,k<<1,L,mid,x)+rk(a,b,k<<1|1,mid,R,x); } int getx(int a,int b,int k){ int L=0,R=100000000; while(R-L>1){ int mid=(L+R)>>1; int k1=rk(a,b+1,1,1,n+1,mid)+1; int k2=rk(a,b+1,1,1,n+1,mid+1); if(k1<=k&&k<=k2)return mid; if(k2<k){ L=mid; } else if(k1>k){ R=mid; } } int k1=rk(a,b+1,1,1,n+1,L);k1++; int k2=rk(a,b+1,1,1,n+1,L+1); if(k1<=k&&k<=k2)return L; else return R; } int pre(int a,int b,int k,int L,int R,int x){ int mid=(L+R)>>1; if(a<=L&&R<=b)return dat[k].Pre(x); if(b<=mid)return pre(a,b,k<<1,L,mid,x); if(a>=mid)return pre(a,b,k<<1|1,mid,R,x); return max(pre(a,b,k<<1,L,mid,x),pre(a,b,k<<1|1,mid,R,x)); } int nxt(int a,int b,int k,int L,int R,int x){ int mid=(L+R)>>1; if(a<=L&&R<=b)return dat[k].Nxt(x); if(b<=mid)return nxt(a,b,k<<1,L,mid,x); if(a>=mid)return nxt(a,b,k<<1|1,mid,R,x); return min(nxt(a,b,k<<1,L,mid,x),nxt(a,b,k<<1|1,mid,R,x)); } void update(int a,int k,int L,int R,int x,int y){ dat[k].Delete(x); dat[k].Insert(y); if(L+1==R)return; int mid=(L+R)>>1; if(a<mid)update(a,k<<1,L,mid,x,y); else update(a,k<<1|1,mid,R,x,y); } void init(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n+1); } void AskRk(){ int L,R,x; scanf("%d%d%d",&L,&R,&x); printf("%d ",rk(L,R+1,1,1,n+1,x)+1); } void AskNum(){ int L,R,k; scanf("%d%d%d",&L,&R,&k); printf("%d ",getx(L,R,k)); } void AskUpd(){ int pos,x; scanf("%d%d",&pos,&x); update(pos,1,1,n+1,a[pos],x); a[pos]=x; } void AskPre(){ int L,R,x; scanf("%d%d%d",&L,&R,&x); int ans=pre(L,R+1,1,1,n+1,x); printf("%d ",(ans<x?ans:-INF)); } void AskNxt(){ int L,R,x; scanf("%d%d%d",&L,&R,&x); int ans=nxt(L,R+1,1,1,n+1,x); printf("%d ",(ans>x?ans:INF)); } void solve(){ int opt; while(m--){ scanf("%d",&opt); switch(opt){ case 1:AskRk();break; case 2:AskNum();break; case 3:AskUpd();break; case 4:AskPre();break; case 5:AskNxt(); } } } int main() { // freopen("data.in","r",stdin); // freopen("my.out","w",stdout); init(); solve(); return 0; }