main
黄海 2 years ago
parent e20e6c4f2c
commit 6ac9254c36

@ -57,7 +57,7 @@ void dfs2(int u, int fa) {
if (v == fa) continue;
// g[u] * (pre[v] * suff[v])解析:
// u给v带来的影响不光是u为根的子树这些叶子的贡献还有重要的一部份就是u的fa[u]及其父、叔叔、大爷、爷爷、二爷爷、老太爷、二老太爷来来的方案数
// 这些由系带来的方案数汇聚到g[u]里
// 这些由系带来的方案数汇聚到g[u]里
g[v] = (g[u] * (pre[v] * suff[v] % mod) % mod + 1) % mod;
dfs2(v, u);
}

@ -0,0 +1 @@
<mxfile host="Electron" modified="2024-01-19T08:33:33.491Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.9.6 Chrome/89.0.4389.128 Electron/12.0.16 Safari/537.36" etag="imkIpv5HMcaimx9pWHR4" version="14.9.6" type="device"><diagram id="94e1Sp-mJR-dtS64sxpf" name="第 1 页">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</diagram></mxfile>

@ -1280,18 +1280,47 @@ signed main() {
先计算钦定 $1$ 号点为根并染黑的方案数。
**状态转移方程**
设 $f_u$ 表示将 $u$ 号点染黑,且其子树内黑点构成连通块的方案数。易见,对于其每一个子节点
$v$,都有染黑和不染黑两种选择:染黑则方案数为 $f_v$ ;不染黑则 $v$ 的整棵子树都只能为白,方案数为 $1$。故
$$\large f_u= \prod_{v \in son_u} (f_v+1) $$
① $f[u]$:将 $u$ 号点染黑,且其子树内黑点构成连通块的方案数。易见,对于其每一个子节点 $v$,都有染黑和不染黑两种选择:染黑则方案数为 $f_v$ ;不染黑则 $v$ 的整棵子树都只能为白,方案数为 $1$。故$$\displaystyle \large f_u= \prod_{v \in son_u} (f_v+1) $$
② $g[u]$:注意!这里的$g[u]$与一般的换根$DP$不一样!
此处:$g[u]$表示$u$的父系带来的方案数。
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401191630870.png)
**答案**
对于以$v$为全局根的树而言,$f[v]*g[v]$就是答案。其实是左边蓝色线内的所有可能方案数,乘以,右边绿色线内的所有可能方案数,是就是所有方案数。
最后,所以节点逐个输出自己的$f[i]*g[i]$就可以了。
> **解释**
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401180842993.png)
**初始化**
当 $u$ 为叶子时,显然 $f_u =1$,与初始化要求相同。
当 $u$ 为叶子时,显然 $f[u] =1$,与初始化要求相同。
> 解释:**对于每一个点,求强制给该点染上黑色时,整棵树上的黑点构成一个连通块的染色方案数。** 这是题目的要求!当一个子树中只有一个点时,还要强制给该点染上黑色,那就只有一种方案。
现在考虑换根。不难理解,如果$v \in son[u]$,换根时消去 $v$ 对 $u$ 的贡献,再将 $u$ 的贡献乘到 $v$ 上。
**第一遍$dfs$**
```c++
void dfs1(int u, int fa) {
f[u] = 1; // 以u为根的子树不管它是不是有子孙节点最起码可以把u染成黑色这样就可以有1种方案
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
dfs1(v, u);
f[u] = f[u] * (f[v] + 1) % mod; // 全白也是一种方案对于v子树而言它并不是只能提供以v染成黑色的所有方案还有一种v没有染成黑色的方案 }
```
**第二遍$dfs$**
现在考虑换根。
不难理解,如果$v \in son[u]$,换根时消去 $v$ 对 $u$ 的贡献,再将 $u$ 剩余贡献乘到 $ans[v]$ 上。
- 消去 $v$ 对 $u$ 的贡献:
@ -1307,7 +1336,21 @@ $$\large f_u= \prod_{v \in son_u} (f_v+1) $$
这里,对于每一个点 $u$,处理出 $f_{v∈son[u]}+1$ 的 **前缀积** 和 **后缀积**,即可解决求出消去一个子树贡献后的答案的问题。
#### 计算前缀积、后缀积的三种办法
**除法与模的处理办法**
我们面对的是$g[v]=f[u]/(f[v]+1)$
求方案数由于数值太大肯定会爆掉long long,题目也很 **温馨**~~恶心~~)给出了使用对$mod$取模的办法进行规避$long$ $long$ 越界。按国际惯例应该是一路计算过来一路取模计算式子中出现了除法联想到了逆元。但费马小定理求逆元要求模必须是质数现在给定的mod可没有说必须是质数所以无法使用逆元来求解。
不让用除法逆元那怎么处理除法+取模呢?
答案就是:**前缀积+后缀积**
因为根据题意,$f[u]=(f[v1]+1)*(f[v2]+1)*(f[v3]+1)*(f[v4]+1)*....*$
不让我用除法我就不用除法我只需要记录v的所有哥哥们的贡献乘积%$mod$,和,所以弟弟们的贡献乘积%$mod$,$pre[v]*suff[v]=f[u]/(f[v]+1)$
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401191633824.png)
#### 计算前缀积、后缀积的三种办法
**方法$1$**
```cpp {.line-numbers}

Loading…
Cancel
Save