zoukankan      html  css  js  c++  java
  • 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
    ",Getdep(nn));
    		}
    		if(opty==4){
    			map<int,int>::iterator it=ma.begin();
    			int x=it->second;
    			printf("%d
    ",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
    ",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
    ",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
    ",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;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    php 扩展模块安装过程
    nginx 配置若干问题
    df 显示 100%的问题
    pcre 不支持 utf 的问题
    服务器TCP连接中 TIME_WAIT 状态过多
    Linux 运维笔试题(一)答案
    Linux 运维笔试题(一)
    Java 内存监控(一)之 jps命令
    python 入门
    Java 内存监控命令简介(零)
  • 原文地址:https://www.cnblogs.com/zzyer/p/8454343.html
Copyright © 2011-2022 走看看