发现旋最小值到根 最小值深度变为1 他的右子树深度不变 其他都加1
旋最大值类似 这个只要线段树就好了 怎么求子树 看他的father
插入操作 找出前驱和后继 一定是祖先子孙关系 新点往深度大的下面挂
#include
#include
#include
#include
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=100005;
int sx[N],icnt;
inline int Bin(int x){
return lower_bound(sx+1,sx+icnt+1,x)-sx;
}
int T[N<<2];
inline void Add(int x,int l,int r,int ql,int qr,int t){
if (ql>qr) return;
if (ql<=l && r<=qr)
return void(T[x]+=t);
if (T[x]) T[x<<1]+=T[x],T[x<<1|1]+=T[x],T[x]=0;
int mid=(l+r)>>1;
if (ql<=mid) Add(x<<1,l,mid,ql,qr,t);
if (qr>mid) Add(x<<1|1,mid+1,r,ql,qr,t);
}
inline void Modify(int x,int l,int r,int t,int a){
if (l==r)
return void(T[x]=a);
if (T[x]) T[x<<1]+=T[x],T[x<<1|1]+=T[x],T[x]=0;
int mid=(l+r)>>1;
if (t<=mid) Modify(x<<1,l,mid,t,a);
else Modify(x<<1|1,mid+1,r,t,a);
}
inline int Query(int x,int l,int r,int t){
if (l==r)
return T[x];
if (T[x]) T[x<<1]+=T[x],T[x<<1|1]+=T[x],T[x]=0;
int mid=(l+r)>>1;
if (t<=mid) return Query(x<<1,l,mid,t);
else return Query(x<<1|1,mid+1,r,t);
}
int m;
int ord[N],x[N];
set<int> Set;
typedef set<int>::iterator IT;
int fat[N],ch[N][2];
inline int D(int x){
return Query(1,1,icnt,x);
}
inline void setc(int x,int y,int d){
int dep=D(x); ch[x][d]=y;
Modify(1,1,icnt,y,dep+1);
fat[y]=x; Set.insert(y);
printf("%d\n",dep+1);
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(m);
for (int i=1;i<=m;i++){
read(ord[i]); if (ord[i]==1) read(x[i]),sx[++icnt]=x[i];
}
sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1;
for (int i=1;i<=m;i++) if (ord[i]==1) x[i]=Bin(x[i]);
int rt;
for (int i=1;i<=m;i++)
if (ord[i]==1){
if (Set.empty())
Modify(1,1,icnt,x[i],1),Set.insert(x[i]),fat[x[i]]=0,rt=x[i],printf("1\n");
else{
IT nxt=Set.lower_bound(x[i]);
if (nxt==Set.begin())
setc(*nxt,x[i],0);
else{
IT pre; pre=nxt;
pre--;
if (nxt==Set.end() || D(*pre)>D(*nxt))
setc(*pre,x[i],1);
else
setc(*nxt,x[i],0);
}
}
}else if (ord[i]==2){
IT it=Set.begin();
int x=*it,d=D(x);
printf("%d\n",d);
if (d==1) continue;
Add(1,1,icnt,1,x-1,1);
Add(1,1,icnt,fat[x],icnt,1);
Modify(1,1,icnt,x,1);
int rc=ch[x][1],p=fat[x];
fat[x]=0;
ch[p][0]=rc; if (rc) fat[rc]=p;
ch[x][1]=rt; fat[rt]=x; rt=x;
}else if (ord[i]==3){
IT it=Set.end(); it--;
int x=*it,d=D(x);
printf("%d\n",d);
if (d==1) continue;
Add(1,1,icnt,1,fat[x],1);
Add(1,1,icnt,x+1,icnt,1);
Modify(1,1,icnt,x,1);
int lc=ch[x][0],p=fat[x];
fat[x]=0;
ch[p][1]=lc; if (lc) fat[lc]=p;
ch[x][0]=rt; fat[rt]=x; rt=x;
}else if (ord[i]==4){
IT it=Set.begin();
int x=*it,d=D(x);
Set.erase(x);
printf("%d\n",d);
if (d==1) {
rt=ch[x][1]; fat[rt]=0;
Add(1,1,icnt,1,icnt,-1);
continue;
}
Add(1,1,icnt,x+1,fat[x]-1,-1);
int rc=ch[x][1],p=fat[x];
fat[x]=0;
ch[p][0]=rc; if (rc) fat[rc]=p;
}else{
IT it=Set.end(); it--;
int x=*it,d=D(x);
Set.erase(x);
printf("%d\n",d);
if (d==1) {
rt=ch[x][0]; fat[rt]=0;
Add(1,1,icnt,1,icnt,-1);
continue;
}
Add(1,1,icnt,fat[x]+1,x-1,-1);
int lc=ch[x][0],p=fat[x];
fat[x]=0;
ch[p][1]=lc; if (lc) fat[lc]=p;
}
return 0;
}