题目描述

小强要在N个孤立的星球上建立起一套通信系统。这套通信系统就是连接N个点的一个树。
这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量。
例如,在上图中,现在一共有了5条边。其中,(3,8)这条边的负载是6,因为有六条简单路径2-3-8,2-3-8-7,3-8,3-8-7,4-3-8,4-3-8-7路过了(3,8)。
现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的询问。

输入

第一行包含两个整数N,Q,表示星球的数量和操作的数量。星球从1开始编号。
接下来的Q行,每行是如下两种格式之一:
A x y 表示在x和y之间连一条边。保证之前x和y是不联通的。
Q x y 表示询问(x,y)这条边上的负载。保证x和y之间有一条边。
1≤N,Q≤100000

输出

对每个查询操作,输出被查询的边的负载。

样例输入

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维护子树信息相关推荐

  1. bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...

  2. BZOJ 4530 大融合 LCT维护子树信息

    题意: N<=1e5个点,Q<=1e5个操作. 支持加一条边(u,v)(保证图是森林).询问经过边(u,v)的简单路径条数(保证(u,v)存在). 分析: 数据结构学傻了的我,表示并不会用 ...

  3. [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并

    [BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...

  4. 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息

    题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...

  5. LCT维护子树信息(BZOJ4530:[BJOI2014]大融合)

    题面 没有权限号的可以去LOJ Sol 大家都知道,\(LCT\)上有许多实边和虚边 实边就是每棵\(Splay\)上的既认父亲又认儿子的边 虚边就是\(Splay\)和\(Splay\)之间只认父亲 ...

  6. BZOJ4530:[BJOI2014]大融合

    Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它 ...

  7. [Bjoi2014]大融合

    [Bjoi2014]大融合 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 394  Solved: 244 [Submit][Status][Dis ...

  8. BZOJ 3639: Query on a tree VII LCT_set维护子树信息

    用 set 维护子树信息,细节较多. Code: #include <cstring> #include <cstdio> #include <algorithm> ...

  9. bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了-- O( nlog ...

  10. 洛谷P4219 大融合(LCT、虚子树)

    解析 本题需要用LCT维护子树大小 然后我就不会了 然后我就用树剖水过去了 又快又好写,真香 现在详细聊聊如何用LCT维护子树信息 每个结点再定义一个新的变量记录所有虚儿子的信息 然后-完了? 告别盲 ...

最新文章

  1. 目标检测之dpm---hog的最优升级版
  2. 【深入Java虚拟机JVM 08】JVM四种引用-强引用、软引用、弱引用、虚引用
  3. Apache RocketMQ 荣获 2021 中国开源云联盟优秀开源项目
  4. shell脚本开发总结
  5. GitKraken - 简单教程
  6. php 期望参数1为资源,PHP:mysql_fetch_array()期望参数1是资源,布尔给定
  7. ZooKeeper入门指南
  8. 让“云”无处不在-Citrix Xenserver之七 转换:XenConver和p2v-legacy
  9. vue @blur v-model数据没有更新问题
  10. dmx512如何帧同步_stm32实现DMX512协议发送与接收(非标)
  11. a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z站?...
  12. PCIe扫盲——基于WinDriver快速开发PCIe驱动简明教程
  13. 【仪器常用操作方法】33500B函数发生器常用操作方法
  14. 老船履带工具使用方法_眉山小型履带车使用方法
  15. 计算机网络 期末复习
  16. KMeans算法的Mapreduce实现
  17. Halcon连接大恒相机
  18. VLOOKUP函数 table_array:无效引用
  19. cpu的基本结构及其工作原理
  20. Asciinema终端SSH录屏神器使用

热门文章

  1. python3 读写json文件,python3没有读取JSON文件righ
  2. 理解RDD的Partition
  3. Hbase过滤器与scala编程
  4. ubuntu安装cairo
  5. 引燃抖音短视频源码开发项目的几点原因
  6. body标签子级被默认client width截断的解决方法
  7. Android Support Library更新到v22.1之AppCompat新特性
  8. iPhone文件系统:创建、重命名以及删除文件
  9. UpdatePanelAnimation
  10. 波形分析--SPI数据