麻麻我终于会写树套树辣
这3个小时没白花QAQ
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1200010;
const int inf=1e9-1;
int tot=2,n,m,c[maxn],root[maxn];
struct seg{
int l,r,rt;
seg *lc,*rc;
seg():rt(0){}
};
seg *Root=new seg();
struct Nodes{
int c[2],fa,rev,s,num,val;
};
struct splay_tree{
Nodes t[maxn];
void push_up(int x){
t[x].s=t[t[x].c[0]].s+t[t[x].c[1]].s+t[x].num;
}
void rotate(int p,int x){
int mark= p==t[x].c[1];
int y=t[p].c[mark^1],z=t[x].fa;
if (t[z].c[0]==x) t[z].c[0]=p;
if (t[z].c[1]==x) t[z].c[1]=p;
if (y) t[y].fa=x; t[x].c[mark]=y;
t[p].fa=z; t[p].c[mark^1]=x; t[x].fa=p;
push_up(x);
}
void splay(int rt,int p,int k){
while (t[p].fa!=k){
int x=t[p].fa,y=t[x].fa;
if (y==k) rotate(p,x);
else if (p==t[x].c[0]^x==t[y].c[0]) rotate(p,x),rotate(p,y);
else rotate(x,y),rotate(p,x);
} push_up(p);
if (!k) root[rt]=p; return;
}
void ins(int rt,int val){
int x=root[rt];
if (!x){
t[++tot].val=val;
t[tot].num=t[tot].s=1;
root[rt]=tot; return;
}
while (t[x].val!=val)
if (t[x].val>val){if(t[x].c[0])x=t[x].c[0];else break;}
else {if(t[x].c[1])x=t[x].c[1];else break;}
if (t[x].val==val){t[x].num++;splay(rt,x,0);return;}
t[++tot].val=val; t[tot].fa=x; t[tot].num=t[tot].s=1;
if (val<t[x].val) t[x].c[0]=tot; else t[x].c[1]=tot;
splay(rt,tot,0); return;
}
int find(int rt,int k){
int x=root[rt];
while (t[x].val!=k)
if (t[x].val>k){if(t[x].c[0])x=t[x].c[0];else break;}
else {if(t[x].c[1])x=t[x].c[1];else break;}
splay(rt,x,0); return x;
}
int qrank(int rt,int k){
int x=find(rt,k);
if (t[x].val>=k) return t[t[x].c[0]].s;
else return t[t[x].c[0]].s+t[x].num;
}
void del(int rt,int val){
int x=root[rt];
while (t[x].val!=val)
if (t[x].val>val){if(t[x].c[0])x=t[x].c[0];else break;}
else{if (t[x].c[1])x=t[x].c[1];else break;}
splay(rt,x,0);
if (t[x].num>1){t[x].num--;return;}
if (!t[x].c[0]){root[rt]=t[x].c[1];t[t[x].c[1]].fa=0;return;}
if (!t[x].c[1]){root[rt]=t[x].c[0];t[t[x].c[0]].fa=0;return;}
int y=t[x].c[0];
while (t[y].c[1]) y=t[y].c[1];
splay(rt,y,x);
t[y].c[1]=t[x].c[1]; t[y].fa=0; t[t[y].c[1]].fa=y;
push_up(y); root[rt]=y;
}
int prec(int rt,int val){
int x=root[rt];
while (t[x].val!=val)
if (t[x].val>val){if(t[x].c[0])x=t[x].c[0];else break;}
else{if (t[x].c[1])x=t[x].c[1];else break;}
if (t[x].val==val){
splay(rt,x,0);
if (!t[x].c[0]) return 1;
x=t[x].c[0];
while (t[x].c[1]) x=t[x].c[1];
return x;
}
while (t[x].fa&&t[x].val>val) x=t[x].fa;
if (t[x].val<val) return x;
return 1;
}
int succ(int rt,int val){
int x=root[rt];
while (t[x].val!=val)
if (t[x].val>val){if (t[x].c[0])x=t[x].c[0];else break;}
else{if (t[x].c[1])x=t[x].c[1];else break;}
if (t[x].val==val){
splay(rt,x,0);
if (!t[x].c[1]) return 2;
x=t[x].c[1];
while (t[x].c[0]) x=t[x].c[0];
return x;
}
while (t[x].fa&&t[x].val<val) x=t[x].fa;
if (t[x].val>val) return x;
return 2;
}
}s;
void build(seg *p,int rt,int l,int r){
p->rt=rt; p->l=l; p->r=r;
for (int i=l;i<r;++i) s.ins(rt,c[i]);
if (l+1==r){p->lc=p->rc=NULL;return;}
else if (l+1<r){
int mid=(l+r)>>1;
p->lc=new seg();
p->rc=new seg();
if (l<mid) build(p->lc,rt<<1,l,mid);
else p->lc=NULL;
if (mid<r) build(p->rc,rt<<1|1,mid,r);
else p->rc=NULL;
}
}
int getrank(seg *p,int l,int r,int k){
if (l<=p->l&&p->r<=r) return s.qrank(p->rt,k);
int mid=(p->l+p->r)>>1,ret=0;
if (l<mid) ret=getrank(p->lc,l,r,k);
if (mid<r) ret+=getrank(p->rc,l,r,k);
return ret;
}
void change(seg *p,int pos,int val){
s.del(p->rt,c[pos]); s.ins(p->rt,val);
if (p->l+1==p->r) return;
int mid=(p->l+p->r)>>1;
if (pos<mid) change(p->lc,pos,val);
else change(p->rc,pos,val);
}
int qpre(seg *p,int l,int r,int val){
if (l<=p->l&&p->r<=r){
int x=s.prec(p->rt,val);
if (s.t[x].val<val) return s.t[x].val;
return -1;
}
int mid=(p->l+p->r)>>1,ret=-1;
if (l<mid) ret=max(ret,qpre(p->lc,l,r,val));
if (mid<r) ret=max(ret,qpre(p->rc,l,r,val));
return ret;
}
int qsuc(seg *p,int l,int r,int val){
if (l<=p->l&&p->r<=r){
int x=s.succ(p->rt,val);
if (s.t[x].val>val) return s.t[x].val;
return inf;
}
int mid=(p->l+p->r)>>1,ret=inf;
if (l<mid) ret=min(ret,qsuc(p->lc,l,r,val));
if (mid<r) ret=min(ret,qsuc(p->rc,l,r,val));
return ret;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%d",&c[i]);
s.t[1].val=-1; s.t[2].val=inf;
build(Root,1,1,n+1);
for (int i=1;i<=m;++i){
int opt,x,y,z;
scanf("%d%d%d",&opt,&x,&y);
if (opt!=3) scanf("%d",&z);
if (opt==1) printf("%d\n",getrank(Root,x,y+1,z)+1);
else if (opt==2){
int L=0,R=1e8,ans=0;
while (L<=R){
int mid=(L+R)>>1;
if(getrank(Root,x,y+1,mid)<z)ans=mid,L=mid+1;
else R=mid-1;
}printf("%d\n",ans);
}else if (opt==3) change(Root,x,y),c[x]=y;
else if (opt==4) printf("%d\n",qpre(Root,x,y+1,z));
else if (opt==5) printf("%d\n",qsuc(Root,x,y+1,z));
}
}