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\n",1LL*siz[x]*siz[y]);
Link(x,y);
}
}
return 0;
}
luogu P4219 [BJOI2014]大融合的更多相关文章
- P4219 [BJOI2014]大融合(LCT)
P4219 [BJOI2014]大融合 对于每个询问$(u,v)$所求的是 ($u$的虚边子树大小+1)*($v$的虚边子树大小+1) 于是我们再开个$si[i]$数组表示$i$的虚边子树大小,维护一 ...
- 洛谷 P4219 [BJOI2014]大融合 解题报告
P4219 [BJOI2014]大融合 题目描述 小强要在\(N\)个孤立的星球上建立起一套通信系统.这套通信系统就是连接\(N\)个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的 ...
- 洛谷P4219 - [BJOI2014]大融合
Portal Description 初始有\(n(n\leq10^5)\)个孤立的点,进行\(Q(Q\leq10^5)\)次操作: 连接边\((u,v)\),保证\(u,v\)不连通. 询问有多少条 ...
- 洛谷P4219 [BJOI2014]大融合(LCT,Splay)
LCT维护子树信息的思路总结与其它问题详见我的LCT总结 思路分析 动态连边,LCT题目跑不了了.然而这题又有点奇特的地方. 我们分析一下,查询操作就是要让我们求出砍断这条边后,x和y各自子树大小的乘 ...
- 洛谷P4219 [BJOI2014]大融合(LCT)
LCT维护子树信息的思路总结与其它问题详见我的LCT总结 思路分析 动态连边,LCT题目跑不了了.然而这题又有点奇特的地方. 我们分析一下,查询操作就是要让我们求出砍断这条边后,x和y各自子树大小的乘 ...
- P4219 [BJOI2014]大融合
传送门 动态维护森林 显然考虑 $LCT$ 但是发现询问求的是子树大小,比较不好搞 维护 $sum[x]$ 表示节点 $x$ 的子树大小,$si[x]$ 表示 $x$ 的子树中虚儿子的子树大小和 那么 ...
- P4219 [BJOI2014]大融合 LCT维护子树大小
\(\color{#0066ff}{ 题目描述 }\) 小强要在\(N\)个孤立的星球上建立起一套通信系统.这套通信系统就是连接\(N\)个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一 ...
- 洛谷 P4219 [BJOI2014]大融合
查询,就相当于先删去这条边,然后查询边的两个端点所在连通块大小,乘起来得到答案,然后再把边加回去 可以用线段树分治做 #pragma GCC optimize("Ofast") # ...
- [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并
[BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...
随机推荐
- 032.SAP上用户无法打开PPE模块,查看并开通用户的PPE权限
01. 用户使用PPE模块之后,提示没有为iPPE工作台分配一个用户参数,如图所示: 02. 如果是管理员账号,则可以点击右下角的问号,来到下面界面 03.点击iPPE 用户分配者几个蓝色的字,进入下 ...
- mysql使用的坑
一: mysql默认是安装记录的物理顺序取数据的,如果不加order by 排序,可能得不到预期的结果. (1) 获取 两个时间点的 id (很快) $sql = ‘select id from a ...
- nginx做维护页面
需求: 一个网站本来有好几个域名,然后也有好几个二级域名,现在停掉了,要求把所有的域名.二级域名,以及具体的文件请求,都指向一个维护页面. 1 单独在vhost里建一个conf文件 server { ...
- redis.conf文件配置
最重要三个配置 1. bind 127.0.0.1 需要注释掉这一行,使别的主机可以访问 2. daemonize no 需要改为yes,使其后台运行 3. requirepass foobared ...
- Web基础之Spring MVC
Spring MVC Spring MVC 说是框架,对Tomcat来说其实就是一个Servlet,关于如何从上古时期的Servlet演化到如今的SpringMVC的,可以看看这篇博文:Spring ...
- UVA - 524 Prime Ring Problem(素数环)(回溯法)
题意:输入n,把1~n组成个环,相邻两个数之和为素数. 分析:回溯法. #pragma comment(linker, "/STACK:102400000, 102400000") ...
- Windows按键消息—虚拟键码(转)
源地址:http://c.biancheng.net/cpp/html/1253.html 虚拟键码保存在WM_KEYDOWN.WM_KEYUP.WM_SYSKEYDOWN和WM_SYSKEYUP消息 ...
- NRF52840与NRF52832的性能区别
蓝牙版本的不断更新,大部分客户慢慢都向往着蓝牙5.0.当然对于前不久NORDIC刚出的蓝牙5.0 NRF52840,很多人都还不是很了解.NRF52840可以说是NRF52832的超强升级版,虽然同样 ...
- arduino中的serial .available()和serial.read()
Serial.available() 的意思是:返回串口缓冲区中当前剩余的字符个数.一般用这个函数来判断串口的缓冲区有无数据,当Serial.available()>0时,说明串口接收到了数据, ...
- Oracle 组函数count()
1.count() 函数的参数除了可以是字段值和表达式外,还可以是“ * ”.如果是字段值或表达式,则忽略空值且考虑重复值:如果是“ * ”,则计算所有的行,也包括空值.如果要查询某字段非重复值的个数 ...