(m1e5)
套路:题目是splay,就显然不是spaly
单旋与双旋的区别:
若为一条链,单旋完了还是链,复杂度不对
双旋我们判断了如果与父亲及祖先在一条直线上则先转祖先,则不会发生这种情况
SOL:
发现其实树的形态变化并不大
例如将最小值旋至根:
- 把最小值的儿子当做其父亲的对应儿子
- 让最小值做根节点
深度变化:除最小值子树+1,即所有>=最小值父亲的值
删除根节点则所有点-1
考虑插入:
插入值的前驱后继一定是连在一起的
插入值只可能做前驱或后继的儿子,于是直接选深度最大的即可
离散化+树状数组+set即可解决
时间复杂度(O(nlog_n))
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=1e5+4;
int m,cn,op[N],uu[N],b[N],rt,ch[N][2],fa[N],t[N];
set<int>s;
inline void add(int x,int v){
for(;x<=cn;x+=x&-x)t[x]+=v;
}
inline int ask(int x){
int ret=0;
for(;x;x-=x&-x)ret+=t[x];
return ret;
}
int main(){
m=read();
for(int i=1;i<=m;i++){
op[i]=read();
if(op[i]==1)uu[i]=b[++cn]=read();
}
sort(b+1,b+cn+1);
cn=unique(b+1,b+cn+1)-b-1;
for(int i=1,u,x,v;i<=m;i++){
if(op[i]==1){
u=lower_bound(b+1,b+cn+1,uu[i])-b;
set<int>::iterator it=s.lower_bound(u);
if(it!=s.end()&&!ch[*it][0]){
ch[*it][0]=u;
fa[u]=*it;
add(u,x=ask(*it)+1-ask(u));
add(u+1,-x);
}
else if(it!=s.begin()&&!ch[*(--it)][1]){
ch[*it][1]=u;
fa[u]=*it;
add(u,x=ask(*it)+1-ask(u));
add(u+1,-x);
}
else{
rt=u;
add(u,x=1-ask(u));
add(u+1,-x);
}
s.insert(u);
cout<<ask(u)<<"
";
}
else if(op[i]==2){
u=*s.begin();
cout<<ask(u)<<"
";
v=fa[u];
if(v){
add(v,1);
fa[ch[u][1]]=v;
ch[v][0]=ch[u][1];
add(u,x=1-ask(u));
add(u+1,-x);
ch[u][1]=rt;
fa[rt]=u;
fa[u]=0;
rt=u;
}
}
else if(op[i]==3){
u=*s.rbegin();
cout<<ask(u)<<"
";
v=fa[u];
if(v){
add(1,1);add(v+1,-1);
fa[ch[u][0]]=v;
ch[v][1]=ch[u][0];
add(u,x=1-ask(u));
add(u+1,-x);
ch[u][0]=rt;
fa[rt]=u;
fa[u]=0;
rt=u;
}
}
else if(op[i]==4){
u=*s.begin();
cout<<ask(u)<<"
";
v=fa[u];
if(v){
add(v,1);
fa[ch[u][1]]=v;
ch[v][0]=ch[u][1];
add(u,x=1-ask(u));
add(u+1,-x);
ch[u][1]=rt;
fa[rt]=u;
fa[u]=0;
rt=u;
}
fa[rt=ch[u][1]]=0;
add(1,-1);
s.erase(u);
}
else{
u=*s.rbegin();
cout<<ask(u)<<"
";
v=fa[u];
if(v){
add(1,1);add(v+1,-1);
fa[ch[u][0]]=v;
ch[v][1]=ch[u][0];
add(u,x=1-ask(u));
add(u+1,-x);
ch[u][0]=rt;
fa[rt]=u;
fa[u]=0;
rt=u;
}
fa[rt=ch[u][0]]=0;
add(1,-1);
s.erase(u);
}
}
return (0-0);
}