若先确定父结点的取值为A
设f(i)为子结点取值和A的gcd为i,且子结点为根的子树相邻结点都互质的方案数
设F(i)为子结点取值和A的gcd为i的倍数,且子结点为根的子树相邻结点都互质的方案数
则f(1) = sigma(mu[d] * F(d)) 条件 d是A的因子
想到,确定一个父结点,一个子结点,就能确定一棵子树,于是我将每条边分解成两条有向边。数组F[e][j]记录的是有向边e起点作为父结点,以终点为根结点,且根结点取值为j的倍数的方案数
每个结点对父亲取值为A的贡献是sigma(mu[d] * F(d))(d是A的因子)
每个结点的方案数就是每个取值的子结点贡献的乘积再求和
设f(i)为子结点取值和A的gcd为i,且子结点为根的子树相邻结点都互质的方案数
设F(i)为子结点取值和A的gcd为i的倍数,且子结点为根的子树相邻结点都互质的方案数
则f(1) = sigma(mu[d] * F(d)) 条件 d是A的因子
想到,确定一个父结点,一个子结点,就能确定一棵子树,于是我将每条边分解成两条有向边。数组F[e][j]记录的是有向边e起点作为父结点,以终点为根结点,且根结点取值为j的倍数的方案数
每个结点对父亲取值为A的贡献是sigma(mu[d] * F(d))(d是A的因子)
每个结点的方案数就是每个取值的子结点贡献的乘积再求和
直接枚举每个点,求F[][]的值,需要剪枝,若这条有向边被访问过,说明这颗子树已经求过了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include