P4271 [USACO18FEB]New Barns

 2023-09-09 阅读 13 评论 0

摘要:题目 P4271 [USACO18FEB]New Barns 做法 这题很长见识啊!! 知识点:两棵树\((A,B)\)联通后,新树的径端点为\(A\)的径端点与\(B\)的径端点的两点 不断加边,那就\(LCT\)维护联通块径端点就好了,两点的简单路径就是把链拉起来的子树 My

题目

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\n",max(Get_dis(x,le[fx]),Get_dis(x,re[fx])));}}
}

转载于:https://www.cnblogs.com/y2823774827y/p/10326219.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/31956.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息