正题
还挺有意思.
手玩一下很容易就可以发现当一个最值spaly的时候只会更改O(1)个节点的关系,并且子树的深度不变,其余深度+1.
一直卡在怎么插入,看题解发现相当于在前驱和后继里面找一个深度最大的,这个很容易证明,首先前驱后继一定是当前点的祖先,因为这个点没有儿子,所以拍扁的时候前驱就是向上走第一个左父亲,后继就是第一个右父亲,深度谁大当然就谁当父亲了.
然后要维护深度的区间加,单点更改,单点查询,直接树状数组就可以.
总结
这玩意性质难找,但找到显然.
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=100010;
#define pii pair<int ,int>
struct ques{
int type,x;
}q[N];
struct node{
int ls,rs,fa;
}s[N];
pii a[N];
int n,m,num[N],X,rt,tot;
long long sum[N],dep,pre;
set<int> S;
set<int>::iterator it;
bool cmp(const pii&a,const pii&b){return a.first<b.first;}
void add(int x,long long t){for(int i=x;i<=n;i+=lowbit(i)) sum[i]+=t;}
long long gs(int x){long long tot=0;for(int i=x;i;i-=lowbit(i)) tot+=sum[i];return tot;}
void sn(int x,int t){pre=gs(x);add(x,t-pre);add(x+1,pre-t);}
void ins(int x){
s[x].ls=s[x].rs=s[x].fa=0;
if(rt==0) rt=x,dep=1;
else{
it=S.lower_bound(x);
if(it!=S.end() && !s[*it].ls) s[X=*it].ls=x;
else it--,s[X=*it].rs=x;
s[x].fa=X;dep=gs(X)+1;
}
S.insert(x);sn(x,dep);
}
void zig(){
it=S.begin();X=*it;dep=gs(X);
if(X!=rt) {
add(1,1);
if(X+1<=s[X].fa-1) add(X+1,-1),add(s[X].fa,1);
sn(X,1);s[s[X].fa].ls=s[X].rs;s[s[X].rs].fa=s[X].fa;
s[rt].fa=X;s[X].rs=rt;rt=X;s[X].fa=0;
}
}
void zag(){
it=S.end();it--;X=*it;dep=gs(X);
if(X!=rt){
add(1,1);
if(s[X].fa+1<=X-1) add(s[X].fa+1,-1),add(X,1);
sn(X,1);s[s[X].fa].rs=s[X].ls;s[s[X].ls].fa=s[X].fa;
s[rt].fa=X;s[X].ls=rt;rt=X;s[X].fa=0;
}
}
void zig_(){
zig();add(1,-1);
it=S.begin();S.erase(it);
s[rt=s[rt].rs].fa=0;
}
void zag_(){
zag();add(1,-1);
it=S.end();it--;S.erase(it);
s[rt=s[rt].ls].fa=0;
}
int main(){
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&q[i].type);
if(q[i].type==1) scanf("%d",&q[i].x),a[++n].first=q[i].x,a[n].second=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++) q[a[i].second].x=i;
for(int i=1;i<=m;i++){
if(q[i].type==1) ins(q[i].x);
if(q[i].type==2) zig();
if(q[i].type==3) zag();
if(q[i].type==4) zig_();
if(q[i].type==5) zag_();
printf("%lld\n",dep);
}
}