BZOJ 4825 [Hnoi2017]单旋
题解:LCT维护Splay形态
Splay后发现只会有几个点发生变化,用LCT维护一下就可以了
在Splay中维护siz
还可以用Splay维护DFS序,旋转后DFS序不变,深度以子树为单位变化
天真的我以为直接模拟Splay可以A掉QWQ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int maxn=100009;
int T;
map<int,int>ma;
int tfa[maxn],tch[maxn][2];
int root,nn;
int fa[maxn],ch[maxn][2],siz[maxn],rev[maxn];
inline int son(int x){
if(ch[fa[x]][1]==x)return 1;
else return 0;
}
inline void pushup(int x){
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
inline bool isroot(int x){
return (ch[fa[x]][0]!=x)&&(ch[fa[x]][1]!=x);
}
inline void pushdown(int x){
if(rev[x]){
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
}
void Downfa(int x){
if(!isroot(x))Downfa(fa[x]);
pushdown(x);
}
inline void Rotate(int x){
int y=fa[x];
int z=fa[y];
int b=son(x),c=son(y);
int a=ch[x][b^1];
if(!isroot(y))ch[z][c]=x;
fa[x]=z;
if(a)fa[a]=y;
ch[y][b]=a;
fa[y]=x;ch[x][b^1]=y;
pushup(y);pushup(x);
}
void Splay(int x){
Downfa(x);
while(!isroot(x)){
int y=fa[x];
if(isroot(y)){
Rotate(x);
}else{
if(son(x)==son(y)){
Rotate(y);Rotate(x);
}else{
Rotate(x);Rotate(x);
}
}
}
}
void Access(int x){
for(int t=0;x;t=x,x=fa[x]){
Splay(x);ch[x][1]=t;pushup(x);
}
}
void Makeroot(int x){
Access(x);Splay(x);rev[x]^=1;
}
void Linkp(int x,int y){
Makeroot(x);fa[x]=y;
}
void Cutp(int x,int y){
Makeroot(x);Access(y);Splay(y);
fa[ch[y][0]]=0;ch[y][0]=0;pushup(y);
}
int Getdep(int x){
Access(x);Splay(x);return siz[x];
}
int main(){
scanf("%d",&T);
while(T--){
if(root)Makeroot(root);
int opty,x;
scanf("%d",&opty);
if(opty==1){
scanf("%d",&x);
ma[x]=++nn;siz[nn]=1;
if(root==0){
root=nn;
}else{
map<int,int>::iterator it1=ma.lower_bound(x);
map<int,int>::iterator it2=ma.upper_bound(x);
if(it1==ma.begin()){//只有后继
Linkp(nn,it2->second);
tfa[nn]=it2->second;
tch[it2->second][0]=nn;
}else if(it2==ma.end()){//只有前驱
--it1;
Linkp(nn,it1->second);
tfa[nn]=it1->second;
tch[it1->second][1]=nn;
}else{
--it1;
int dep1=Getdep(it1->second);
int dep2=Getdep(it2->second);
if(dep1>dep2){
Linkp(nn,it1->second);
tfa[nn]=it1->second;
tch[it1->second][1]=nn;
}else{
Linkp(nn,it2->second);
tfa[nn]=it2->second;
tch[it2->second][0]=nn;
}
}
}
printf("%d\n",Getdep(nn));
}
if(opty==4){
map<int,int>::iterator it=ma.begin();
int x=it->second;
printf("%d\n",Getdep(x));
if(x==root){
root=tch[x][1];
tfa[tch[x][1]]=0;
if(tch[x][1])Cutp(tch[x][1],x);
}else{
Cutp(x,tfa[x]);
tch[tfa[x]][0]=0;
int y=tch[x][1];
if(y){
Cutp(x,y);
Linkp(tfa[x],y);
tfa[y]=tfa[x];
tch[tfa[x]][0]=y;
}
}
ma.erase(it->first);
}
if(opty==5){
map<int,int>::iterator it=ma.end();--it;
int x=it->second;
printf("%d\n",Getdep(x));
if(x==root){
root=tch[x][0];
tfa[tch[x][0]]=0;
if(tch[x][0])Cutp(tch[x][0],x);
}else{
Cutp(x,tfa[x]);
tch[tfa[x]][1]=0;
int y=tch[x][0];
if(y){
Cutp(x,y);
Linkp(tfa[x],y);
tfa[y]=tfa[x];
tch[tfa[x]][1]=y;
}
}
ma.erase(it->first);
}
if(opty==2){
map<int,int>::iterator it=ma.begin();
int x=it->second;
printf("%d\n",Getdep(x));
if(x==root){
}else{
Cutp(x,tfa[x]);
tch[tfa[x]][0]=0;
int y=tch[x][1];
if(y){
Cutp(x,y);
Linkp(tfa[x],y);
tfa[y]=tfa[x];
tch[tfa[x]][0]=y;
}
Linkp(root,x);
tfa[x]=0;tch[x][1]=root;
tfa[root]=x;root=x;
}
}
if(opty==3){
map<int,int>::iterator it=ma.end();--it;
int x=it->second;
printf("%d\n",Getdep(x));
if(x==root){
}else{
Cutp(x,tfa[x]);
tch[tfa[x]][1]=0;
int y=tch[x][0];
if(y){
Cutp(x,y);
Linkp(tfa[x],y);
tfa[y]=tfa[x];
tch[tfa[x]][1]=y;
}
Linkp(root,x);
tfa[x]=0;tch[x][0]=root;
tfa[root]=x;root=x;
}
}
}
return 0;
}
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!

浙公网安备 33010602011771号