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; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!