zoukankan      html  css  js  c++  java
  • P4271 [USACO18FEB]New Barns

    题目

    P4271 [USACO18FEB]New Barns

    做法

    这题很长见识啊!!

    知识点:两棵树((A,B))联通后,新树的径端点为(A)的径端点与(B)的径端点的两点

    不断加边,那就(LCT)维护联通块径端点就好了,两点的简单路径就是把链拉起来的子树

    My complete code

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef int LL;
    const LL maxn=1e6;
    inline LL Read(){
    	LL x(0),f(1);char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    	return x*f;
    }
    LL m,tot;
    LL son[maxn][2],fa[maxn],size[maxn],f[maxn],le[maxn],re[maxn],r[maxn],sta[maxn];
    inline void Update(LL x){
    	size[x]=size[son[x][0]]+size[son[x][1]]+1;
    }
    inline bool Notroot(LL x){
    	return son[fa[x]][0]==x||son[fa[x]][1]==x;
    }
    inline void Pushr(LL x){
    	swap(son[x][0],son[x][1]),r[x]^=1;
    }
    inline void Pushdown(LL x){
    	if(r[x]){
    		if(son[x][0]) Pushr(son[x][0]);
    		if(son[x][1]) Pushr(son[x][1]);
    		r[x]=0;
    	}
    }
    inline void Rotate(LL x){
    	LL y(fa[x]),z(fa[y]),lz=(son[y][1]==x);
    	if(Notroot(y)) son[z][son[z][1]==y]=x; fa[x]=z;
        son[y][lz]=son[x][lz^1];
        if(son[y][lz]) fa[son[y][lz]]=y;
        son[x][lz^1]=y; fa[y]=x;
        Update(y),Update(x);
    }
    inline void Splay(LL x){
    	LL y(x),top(0);
    	sta[++top]=y;
    	while(Notroot(y)) sta[++top]=y=fa[y];
    	while(top) Pushdown(sta[top--]);
    	while(Notroot(x)){
    		y=fa[x];
    		if(Notroot(y)){
    			LL z(fa[y]);
    			if(((son[y][1]==x)^(son[z][1]==y))==0) Rotate(y);
    			else Rotate(x);
    		}Rotate(x);
    	}
    }
    inline void Access(LL x){
    	for(LL y=0;x;y=x,x=fa[x])
    		Splay(x),son[x][1]=y,Update(x);
    }
    inline void Makeroot(LL x){
    	Access(x),Splay(x),Pushr(x);
    }
    inline void Split(LL x,LL y){
    	Makeroot(x),Access(y),Splay(y);
    }
    inline void Link(LL x,LL y){
    	Makeroot(x),fa[x]=y;
    }
    inline LL Get_dis(LL x,LL y){
    	Split(x,y); return size[y]-1;
    }
    
    LL Get_fa(LL x){
    	return f[x]=(f[x]==x?x:Get_fa(f[x]));
    }
    int main(){
    	m=Read();
    	while(m--){
    		char ch; scanf(" %c",&ch);
    		if(ch=='B'){
    			++tot, size[tot]=1;
    			LL x(Read());
    			if(x==-1)
    			    f[tot]=le[tot]=re[tot]=tot;
    			else{
    				Link(tot,x); f[tot]=x=Get_fa(x);
    				LL l1(Get_dis(le[x],tot)),l2(Get_dis(re[x],tot)),l3(Get_dis(le[x],re[x]));
    				if(l1>l2&&l1>l3)
    				    re[x]=tot;
    				else if(l2>l3)
    				    le[x]=tot;
    			}
    		}else{
    			LL x(Read()),fx=Get_fa(x);
    			printf("%d
    ",max(Get_dis(x,le[fx]),Get_dis(x,re[fx])));
    		}
    	}
    }
    
  • 相关阅读:
    HNOI2018退役记
    codeforces 960G Bandit Blues
    codeforces 933D A Creative Cutout
    tyvj1953 Normal
    loj6119 「2017 山东二轮集训 Day7」国王
    codeforces 293E Close Vertices
    bzoj1808 [Ioi2007]training 训练路径
    bzoj2219 数论之神
    bzoj4361 isn
    loj2064[HAOI2016]找相同字符
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10326219.html
Copyright © 2011-2022 走看看