JZOJ5058. 【GDSOI2017模拟4.13】采蘑菇
题目描述:
A君住在魔法森林里,魔法森林可以看做一棵n个结点的树,结点从1~n编号。树中的每个结点上都生长着蘑菇。蘑菇有许多不同的种类,但同一个结点上的蘑菇都是同一种类,更具体地,i号结点上生长着种类为c[i]的蘑菇。
现在A君打算出去采蘑菇,但他并不知道哪里的蘑菇更好,因此他选定起点s后会等概率随机选择树中的某个结点t作为终点,之后从s沿着(s,t)间的最短路径走到t.并且A君会采摘途中所经过的所有结点上的蘑菇。
现在A君想知道,对于每一个结点u,假如他从这个结点出发,他最后能采摘到的蘑菇种类数的期望是多少。为了方便,你告诉A君答案*n的值即可。
数据范围:
30%的数据:n <= 2000
另有20%的数据:给出的第i条边为{i,i+1}
另有20%的数据:蘑菇的种类最多3种
100%的数据:1 <= n <= 3*10^5 , 0 <= c[i] <= n
这道题有虚数做法,有换根线段树做法,也有点分治做法。
它们(除了虚树,因为我并不会)都带有一只log。虽然这道题时限比较宽松,但是有一位dalao想出了O(n)的做法。
我们随便取一个点为根。
定义一下:
s z x sz_{x} szx为以 x x x为根的子树的大小, u p x up_{x} upx为从 x x x到根的路径上,离 x x x最近的且颜色与 x x x相同的祖先的与 x x x在同一条路径上的儿子。
假设我们做到节点 u u u,颜色为 c c c。考虑经过 x x x的路径的贡献。
黑色的节点表示与u同色的节点。
f f f为离 x x x最近的且颜色与 x x x相同的祖先, x x x为 u p u up_{u} upu。
假设以 x x x为根的子树内的节点为起点,其它节点为终点,那么很显然以 x x x为根的子树内每个节点都能接受到其它节点个数的贡献,也就是 n − s z x n-sz_{x} n−sz