
=====树上启发式合并=====
Qingo呀
老菜鸡。
展开
-
2020CCPC 长春 F. Strange Memory (树上启发式合并+按位算贡献)
题链:https://codeforces.com/gym/102832/problem/F题意:求,翻译一下就是求当的和。思路:做过类似的题,传送门。看到LCA,可以考虑将问题转化到子树上。因为,以u为LCA的无序对(v1,v2)一定在u的子树中,其中v1,v2要属于u的不同儿子。那么,我们可以维护子树中每个数的下标集合。在计算u子树的答案时,统计u的轻儿子v的贡献时,要先统计答案,再将v的子树里的数加上。这样是为了避免将v的子树的无序对(v1,v2)统计为答案,虽然,但显然(v1,...原创 2020-12-03 16:27:10 · 401 阅读 · 0 评论 -
CF 1009F Dominant Indices (dsu on tree)
题目链接:https://codeforces.com/contest/1009/problem/F题意:n个点的树,根为1。定义为y的个数,y满足:1.x是y的祖先。2.x到y的路径包含i条边。对于每个节点x求一个值j,j满足思路:将问题转化为子树上就是求u的子树中,节点个数最多且深度最小的一层。直接维护每层节点的个数,计算u的答案时直接记一下当前节点个数最多且深度最小的深度即可,假设为d,那么答案就是d-deep[u]。代码:#include <bits/stdc原创 2020-11-21 16:32:25 · 564 阅读 · 0 评论 -
洛谷 4149 [IOI2011]Race (dsu on tree)
题目链接:https://www.luogu.com.cn/problem/P4149题意:给一棵树,n个点,每条边有权。求一条简单路径,权值和等于k,且边的数量最小。思路:将问题转化为子树中,对于节点u,可以把u看作简单路径两个端点v1和v2的LCA。预处理每个节点到根的距离(数组dis)和深度(数组dep),问题转化为求最小的dep[v1]+dep[v2]-2*dep[u]使得dis[v1]+dis[v2]-2*dis[u]==k 。维护子树中每个dis的最小深度。在计算u子树的答案时,要先更.原创 2020-11-21 16:16:38 · 376 阅读 · 0 评论 -
CF 208E Blood Cousins (dus on tree)
题目链接:https://codeforces.com/contest/208/problem/E题意:n个节点,组成森林。m个询问,一个询问由(v,p)组成,问v的p-cousin有多少,v的p-cousin(v1)指v,v1在同一层且他们和LCA(v,v1)距离为p。思路:将询问转化为子树上,对于一个询问(v,p),我们从下往上找v的第p个祖先(u)[我用的倍增],那么询问的答案就是问u的子树中,深度为deep[u]+p节点的个数-1。维护每个深度有多少节点即可。代码:#include原创 2020-11-21 15:46:34 · 170 阅读 · 0 评论 -
CF 246E Blood Cousins Return (dsu on tree)
题目链接:https://codeforces.com/contest/246/problem/E题意:n个点,每个节点有一个名字,组成一个森林。m个询问,每个询问由(v,k)组成,问v的子树中,深度为k(v的深度为1)的的节点有多少不同的名字。思路:将询问转化为子树中,询问(v,k)问的就是v的子树中,深度为deep(v)+k的节点有多少不同的名字。维护子树中,每个深度不同名字的个数即可。...原创 2020-11-21 12:22:22 · 145 阅读 · 0 评论 -
HackerEarth, The Grass Type (dsu on tree)
题目链接:https://www.hackerearth.com/practice/algorithms/graphs/depth-first-search/practice-problems/algorithm/the-grass-type/题意:n个点,根为1。每个节点i都有一个值。求使得的无序对(u,v)个数。思路:将问题转化为子树中的问题,以u为LCA的无序对(v1,v2)一定在u的子树中,其中v1,v2要属于u的不同儿子。所以,我们维护子树中每个数的数量(我用的unordered_map.原创 2020-11-21 12:02:26 · 217 阅读 · 0 评论 -
埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B 合约数 (dfs+预处理)(dsu on tree)
链接:https://ac.nowcoder.com/acm/contest/9115/B题意:给定一棵n个节点的树,并且根节点的编号为p,第i个节点有属性值vali, 定义F(i): 在以i为根的子树中,属性值是vali的合约数的节点个数。y 是 x 的合约数是指 y 是合数且 y 是 x 的约数。小埃想知道对1000000007取模后的结果。思路:反向思考,对于一个编号u,他自己对其子树中是他合约数的节点的贡献为u。用素数筛的思想,预处理每个数的约数以及是否为合数。假设dfs到一个节点u,先将v原创 2020-11-15 10:54:58 · 161 阅读 · 0 评论 -
SGU 507 Treediff (dsu on tree)
题目链接:https://codeforces.com/problemsets/acmsguru/problem/99999/507题意:n个点,组成一个树,根为1。这个树有m个叶子节点,每个叶子节点上都有一个值。对于n-m个非叶子节点,输出其子树上的叶子节点中,每对节点值的差的绝对值的最小值。思路:有mp维护子树中叶节点的值,每插入一个值时,用第一个比他小的值和第一个比他大的值和他作差,更新答案。代码:#include <bits/stdc++.h>#define ll l原创 2020-11-21 11:34:57 · 211 阅读 · 0 评论 -
CF 570D Tree Requests (dsu on tree)
题目链接:https://codeforces.com/contest/570/problem/D题意:n条边,m个询问,每个节点上都有一个字符(仅为小写英文字符)。每个询问由v和h组成,问v的子树中,深度为h的节点任意排列是否能组成回文字符串(空字符串也是),每个询问输出“Yes”或“No”。思路:维护每个深度中每个字符的个数,最多只能有一个字符的个数为奇数。给每个询问建图,把每个询问归到相应v的子树中即可。代码:#include <cstdio>#include <原创 2020-11-21 11:17:08 · 157 阅读 · 0 评论 -
CF 600E Lomsat gelral (dsu on tree)
题目链接:https://codeforces.com/contest/600/problem/E题意:给一个n的点的树,根为1。子树u的支配颜色为出现次数最多的颜色(可能有多个),求每个子树中支配颜色的和。思路:常规套路,其实只需要维护颜色的个数。其实计算每个子树答案的时候,算一下最大次数以及和就行。由于这是做的第一个题,所以我另外维护了一个ma数组(出现的最大次数)、sum数组(当前出现次数最多的颜色的和)。代码:#include <bits/stdc++.h>#defi原创 2020-11-21 11:03:04 · 163 阅读 · 0 评论 -
树上启发式合并(dsu on tree)学习笔记【理解+套路+例题及题解】
一、理解先从一个典型的例题开始,树的每个节点都有一个颜色,求某个节点v的子树中颜色c的个数。暴力的话,就是对于每一个节点都统计一下子树中颜色c的个数,复杂度为。现在,我们来优化。可以发现我们做了很多重复的工作,如果能利用一些工作的结果那就好了。这里要引入轻/重儿子的思想(好像就是轻重链,树链剖分。。。。),可以证明从整棵树的根节点到树中任意一点的路径上最多有条轻边。(相关定义及证明请参考博客:https://www.cnblogs.com/zwfymqz/p/9683124.html)。所以我们把重..原创 2020-11-20 22:44:06 · 466 阅读 · 0 评论