zoukankan      html  css  js  c++  java
  • luogu P4219 [BJOI2014]大融合

    题解:原来LCT也能维护子树信息,我太Naive了

    用LCT维护当前子树节点个数

    具体做法维护siz[x]=当前Splay子树和指向当前Splay子树的虚边所代表的节点个数

    auxsiz[x]=指向x节点的虚边代表的节点个数

    Link的时候x,y都要makeroot一下(针对我的写法)

    然后就在LCT的基础上维护auxsiz即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=100009;
    
    
    int n,TT;
    
    int fa[maxn]={0},ch[maxn][2]={0},siz[maxn]={0},auxsiz[maxn]={0},rev[maxn]={0};
    inline bool isroot(int x){
    	return (ch[fa[x]][0]!=x)&&(ch[fa[x]][1]!=x);
    }
    inline void pushup(int x){
    	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1+auxsiz[x];
    }
    inline int son(int x){
    	if(ch[fa[x]][0]==x)return 0;
    	else return 1;
    }
    inline void pushdown(int x){
    	if(rev[x]){
    		rev[x]^=1;
    		rev[ch[x][0]]^=1;
    		rev[ch[x][1]]^=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;){
    		Splay(x);
    		auxsiz[x]+=siz[ch[x][1]];
    		auxsiz[x]-=siz[t];
    		ch[x][1]=t;
    		pushup(x);
    		t=x;x=fa[x];
    	}
    }
    void Makeroot(int x){
    	Access(x);Splay(x);rev[x]^=1;
    }
    void Link(int x,int y){
    	Makeroot(x);Makeroot(y);fa[x]=y;
    	auxsiz[y]+=siz[x];pushup(y);
    }
    void Cut(int x,int y){
    	Makeroot(x);Access(y);Splay(y);
    	fa[ch[y][0]]=0;ch[y][0]=0;
    	pushup(y);
    }
    
    int main(){
    	scanf("%d%d",&n,&TT);
    	for(int i=1;i<=n;++i)siz[i]=1;
    	while(TT--){
    		char opty=getchar();
    		int x,y;
    		while(opty!='Q'&&opty!='A')opty=getchar();
    		scanf("%d%d",&x,&y);
    		if(opty=='A'){
    			Link(x,y);
    		}else{
    			Cut(x,y);
    			Splay(x);Splay(y);
    			printf("%lld
    ",1LL*siz[x]*siz[y]);
    			Link(x,y);
    		}
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    负载均衡之加权轮询算法(转)
    go 指南学习笔记
    select限制之文件描述符限制
    select的限制
    select实现超时(套接字IO超时设置)
    如何在CentOS 8上安装Puppet
    如何在Ubuntu 20.04 / 18.04或更老版本中安装ifconfig
    关于Ubuntu的Apt安装与使用介绍
    如何在CentOS 8上安装Suricata?
    如何在Ubuntu 20.04上安装PHP Composer
  • 原文地址:https://www.cnblogs.com/zzyer/p/8516538.html
Copyright © 2011-2022 走看看