青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)
题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离。 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 第一种,树形dp+LCA 比赛的时候,我猜测对于不为1的n个数,其中两两互质的对数不会很多,肯定达不到n^2 然后找出所有互质的对数,然后对为1的数进行特殊处理。(初略的估计了下,小于500的大概有50个质数,将n个数平均分到这些数中,最后大概有10000*50*200=10^7) 对所有的非1质数对,采用离线LCA可以搞定。 对于1的特殊情况,只需要用两次dfs,就可以找出所有1到其它点的距离和与1之间的距离和。 第二种,树形dp+容斥 这种方法从边的角度,考虑每一条边会被计算多少次,这也是树上求距离的常用方法。 由于树边都是桥边,所有只要求出边两边联通块之间互质对数。最简单的想法即是枚举每一条边,然后再分别枚举两边区域,这样的复杂度是500*500*10000 很遗憾并没有这么简单。于是用容斥原理进行优化。在枚举某条边的一边的x(1<=x<=500)的时候,考虑右边为x质因子倍数的情况,也就是容斥了。 这样可以将复杂度变为10000*500*k*2^k( k<=4) 官方题解: 附上代码: // // main.cpp // 160701 // // Created by New_Life on 16/7