【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息
题目描述
输入
输出
样例输入
8 6
A 2 3
A 3 4
A 3 8
A 8 7
A 6 5
Q 3 8
样例输出
6
题解
LCT维护子树信息
学了大神的LCT维护子树信息的方式,觉得还算好理解,于是自己yy了这道题。
我们知道,在LCT中的Splay Tree中,access某个点并splay到根,那么它的实儿子记录的信息是这条链的信息,并不是我们想要的子树信息。
而所有实儿子和虚儿子的信息才是我们想要求的子树信息。
但是由于虚儿子“儿子认爹,爹不认儿子”的性质,无法在pushup的时候上传信息。
事实上,我们注意到,对于Splay Tree的所有基本操作,除了access和link以外,都不会对虚儿子的信息进行修改。
那么我们每次在添加虚儿子时,顺便把虚儿子的信息也记录到父亲节点中。
这样我们每次调用一个节点时,将它Splay Tree中实儿子的信息,加上它自身的虚儿子的信息,就是我们想要的子树信息。
于是我们对于每个节点记录两个信息:它的总信息和它虚儿子的信息,pushup时更新x的总信息为:x实儿子的总信息+x虚儿子的信息+x本身的信息。
按照这种方法我们来思考这道题,可以发现所求的答案就是一条边两端点的子树大小乘积,我们把某一个端点定为整棵树的根,可以知道整棵树的大小,而根据另一个节点可以知道一个子树的大小,相减即为另一个子树的大小。
具体的实现:
access操作中割断了实边c[1][x],该边变为了虚边,所以应该加到x的虚儿子信息中,加入了实边t,该边不再是虚边,所以应从x的虚儿子信息中减去。
link操作中为了在加入x时同时更新y的信息,需要makeroot(x),makeroot(y),然后连x->y的虚边(实际上只需要access(y)和splay(y))。
其余的操作,和普通的LCT没有任何区别。
代码中需要注意的是,sum[x]存的是总信息(子树大小),si[x]存的是虚儿子信息(子树除了链以外的大小),不要弄混。
#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;
int fa[N] , c[2][N] , si[N] , sum[N] , rev[N];
char str[5];
void pushup(int x)
{sum[x] = sum[c[0][x]] + sum[c[1][x]] + si[x] + 1;
}
void pushdown(int x)
{if(rev[x]){int l = c[0][x] , r = c[1][x];swap(c[0][l] , c[1][l]) , swap(c[0][r] , c[1][r]);rev[l] ^= 1 , rev[r] ^= 1 , rev[x] = 0;}
}
bool isroot(int x)
{return c[0][fa[x]] != x && c[1][fa[x]] != x;
}
void update(int x)
{if(!isroot(x)) update(fa[x]);pushdown(x);
}
void rotate(int x)
{int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;if(!isroot(y)) c[c[1][z] == y][z] = x;fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;pushup(y) , pushup(x);
}
void splay(int x)
{update(x);while(!isroot(x)){int y = fa[x] , z = fa[y];if(!isroot(y)){if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);else rotate(y);}rotate(x);}
}
void access(int x)
{int t = 0;while(x) splay(x) , si[x] += sum[c[1][x]] - sum[t] , c[1][x] = t , pushup(x) , t = x , x = fa[x];
}
void makeroot(int x)
{access(x) , splay(x) , swap(c[0][x] , c[1][x]) , rev[x] = 1;
}
void split(int x , int y)
{makeroot(x) , makeroot(y);
}
void link(int x , int y)
{split(x , y) , fa[x] = y , si[y] += sum[x] , pushup(y);
}
int main()
{int n , m , i , x , y;scanf("%d%d" , &n , &m);for(i = 1 ; i <= n ; i ++ ) sum[i] = 1;while(m -- ){scanf("%s%d%d" , str , &x , &y);if(str[0] == 'A') link(x , y);else split(x , y) , printf("%lld\n" , (long long)sum[x] * (sum[y] - sum[x]));}return 0;
}
转载于:https://www.cnblogs.com/GXZlegend/p/7061458.html
【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息相关推荐
- bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...
- BZOJ 4530 大融合 LCT维护子树信息
题意: N<=1e5个点,Q<=1e5个操作. 支持加一条边(u,v)(保证图是森林).询问经过边(u,v)的简单路径条数(保证(u,v)存在). 分析: 数据结构学傻了的我,表示并不会用 ...
- [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并
[BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...
- 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息
题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...
- LCT维护子树信息(BZOJ4530:[BJOI2014]大融合)
题面 没有权限号的可以去LOJ Sol 大家都知道,\(LCT\)上有许多实边和虚边 实边就是每棵\(Splay\)上的既认父亲又认儿子的边 虚边就是\(Splay\)和\(Splay\)之间只认父亲 ...
- BZOJ4530:[BJOI2014]大融合
Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它 ...
- [Bjoi2014]大融合
[Bjoi2014]大融合 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 394 Solved: 244 [Submit][Status][Dis ...
- BZOJ 3639: Query on a tree VII LCT_set维护子树信息
用 set 维护子树信息,细节较多. Code: #include <cstring> #include <cstdio> #include <algorithm> ...
- bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了-- O( nlog ...
- 洛谷P4219 大融合(LCT、虚子树)
解析 本题需要用LCT维护子树大小 然后我就不会了 然后我就用树剖水过去了 又快又好写,真香 现在详细聊聊如何用LCT维护子树信息 每个结点再定义一个新的变量记录所有虚儿子的信息 然后-完了? 告别盲 ...
最新文章
- 目标检测之dpm---hog的最优升级版
- 【深入Java虚拟机JVM 08】JVM四种引用-强引用、软引用、弱引用、虚引用
- Apache RocketMQ 荣获 2021 中国开源云联盟优秀开源项目
- shell脚本开发总结
- GitKraken - 简单教程
- php 期望参数1为资源,PHP:mysql_fetch_array()期望参数1是资源,布尔给定
- ZooKeeper入门指南
- 让“云”无处不在-Citrix Xenserver之七 转换:XenConver和p2v-legacy
- vue @blur v-model数据没有更新问题
- dmx512如何帧同步_stm32实现DMX512协议发送与接收(非标)
- a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z站?...
- PCIe扫盲——基于WinDriver快速开发PCIe驱动简明教程
- 【仪器常用操作方法】33500B函数发生器常用操作方法
- 老船履带工具使用方法_眉山小型履带车使用方法
- 计算机网络 期末复习
- KMeans算法的Mapreduce实现
- Halcon连接大恒相机
- VLOOKUP函数 table_array:无效引用
- cpu的基本结构及其工作原理
- Asciinema终端SSH录屏神器使用