其他分享
首页 > 其他分享> > DTOJ #5859. 树论 题解

DTOJ #5859. 树论 题解

作者:互联网

树论

未成年人必须先想 dp。

考虑树形 dp。

我们记 f[u][k] 表示以 \(u\) 为根的子树内,\(u\) 的权值为 \(k\) 的方案数,答案可以直接用 \(f_{u,k} \times k\) 计算。

然后考虑如何转移:

\[\begin{aligned} f_{u,k} &=& \prod_{v\in \operatorname{Son}(u)}\sum_{\gcd(i,k)=1}f_{v,i}\\ &=&\prod_{v}\sum_{i=l_v}^{r_v}f_{v,i}[\gcd(k,i)=1] \end{aligned} \]

反演老套路了。顺便定义 \(f_{v,i}=0(i\not\in[l_v,r_v])\) 以去除烦人的上下界:

\[\begin{aligned} f_{u,k} & = & \prod_v\sum_i f_{v,i} \sum_{d|k,d|i}\mu(d) \\ &=& \prod_v\sum_{d|k}\mu(d)\sum_{d|i}f_{v,i} \end{aligned} \]

嗯。看起来不是很可做,而且让人有种想把第二个和式拆成数论分块的欲望。

不过出现形如 \(\sum_{d|n}\) 的式子,可以回忆一下迪利克雷卷积:

\[f*g(n) = \sum_{d|n} f(d)g(\frac{n}{d}) \]

我们定义一个雷克利迪卷积:

\[f*g(d)=\sum_{d|n} f(n)g(\frac{n}{d}) \]

然后,第二个和式就是 \(f_v*1\) 了,可以 \(O(n\log n)\) 算(因为对于 \(n>r_v\) 时式子为 \(0\),所以只需要考虑到 \(r_v\),即 \(O(r_v\log r_v)\)。

我们记卷出来是 \(g(n)\),那么式子可以变成:

\[f_{u,k} = \prod_v \sum_{d|k}\mu(d)g(d) \]

再定义一个克利迪雷卷积:

\[f*g(n) = \sum_{d|n}f(d)g(d) \]

又是一个可以 \(O(n\log n)\) 求得。我们求出 \(\mu * g(n)\) 记为 \(h(n)\)。

\[f_{u, k} = \prod_{v}h(k) \]

额,直接乘起来就可以了。记 \(A = \max\{r_u\}\),时间复杂度 \(O(nA\log A)\)。

最后还要换根,不过比较简单,删去子树的贡献就乘上逆元即可。

标签:prod,log,卷积,题解,sum,树论,mu,aligned,DTOJ
来源: https://www.cnblogs.com/lingfunny/p/16342391.html