main
黄海 2 years ago
parent 04c141b2c1
commit 9f43b7ed15

@ -34,23 +34,40 @@ void dfs1(int u, int fa) {
son.push_back(v); // 将子节点加入集合,方便之后操作
}
//这里面的t1,t2,其实也可以不用:
//pre[son[0]]:1
//pre[son[1]]: pre[son[0]] * (f[son[1]] + 1) % mod
// 这里面的t1,t2,其实也可以不用:
// pre[son[0]]:1
// pre[son[1]]: pre[son[0]] * (f[son[1-1]] + 1) % mod
//...
//pre[son[i]]: pre[son[i-1]] * (f[son[i]] + 1) % mod
// pre[son[i]]: pre[son[i-1]] * (f[son[i-1]] + 1) % mod
int t1 = 1; // 前缀积取模后的值
int t2 = 1; // 后缀积取模后的值
// int t1 = 1; // 前缀积取模后的值
// 记录前缀积
for (int i = 0; i < son.size(); i++) { // 将儿子数组正着枚举
// 利用静态数组pre,记录每个节点的前缀积取模后的值
pre[son[i]] = t1; // 到我以前,所有结果的累乘积是多少
t1 = t1 * (f[son[i]] + 1) % mod; // 我完成后,需要把我的贡献也乘到累乘积中,以便我的下一个节点计算它的累乘积时使用
}
/* 方法1
for (int i = 0; i < son.size(); i++) { // 将儿子数组正着枚举
// 利用静态数组pre,记录每个节点的前缀积取模后的值
pre[son[i]] = t1; // 到我以前,所有结果的累乘积是多少
t1 = t1 * (f[son[i]] + 1) % mod; // 我完成后,需要把我的贡献也乘到累乘积中,以便我的下一个节点计算它的累乘积时使用
}
*/
// 方法2
if (son.size() > 0) pre[son[0]] = 1;
for (int i = 1; i < son.size(); i++)
pre[son[i]] = pre[son[i - 1]] * (f[son[i - 1]] + 1) % mod;
// 方法3:
/*
for (int i = 0; i < son.size(); i++) {
if (i == 0) {
pre[son[i]] = 1;
continue;
}
pre[son[i]] = pre[son[i - 1]] * (f[son[i - 1]] + 1) % mod;
}*/
// 记录后缀积
int t2 = 1; // 后缀积取模后的值
for (int i = son.size() - 1; i >= 0; i--) { // 将儿子数组倒着枚举
// 利用静态数组suff,记录每个节点的后缀积取模后的值
suff[son[i]] = t2; // 到我以前,所有结果的累乘积是多少
@ -60,10 +77,10 @@ void dfs1(int u, int fa) {
}
void dfs2(int u, int fa) {
g[u] = (g[fa] * (pre[u] * suff[u] % mod) % mod + 1) % mod;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
g[v] = (g[u] * (pre[v] * suff[v] % mod) % mod + 1) % mod;
dfs2(v, u);
}
}

Loading…
Cancel
Save