problem

luogu

给一棵树,对每一个节点染成黑色或白色。

对于每一个节点,求强制把这个节点染成黑色的情况下,所有的黑色节点组成一个联通块的染色方案数,答案对 MMM 取模。

1≤n≤1e5,2≤M≤1e91\le n\le 1e5,2\le M\le 1e91≤n≤1e5,2≤M≤1e9。

solution

换根 dpdpdp。

设 f(i):f(i):f(i): 以 iii 为根的子树,iii 为黑色的合法方案数。(全局是以 111 为根的)

则有:f(u)=∏v∈sonu(f(v)+1)f(u)=\prod_{v\in son_u}(f(v)+1)f(u)=∏v∈sonu​​(f(v)+1)。加一是整棵子树全为白色的方案数。

设 g(i):g(i):g(i): 以 iii 为根的子树,iii 为黑色的合法方案数。(这里的子树指代的是 iii 的祖先及兄弟,即去掉 iii 原来子树的剩余部分)

显然答案为 f(i)∗g(i)f(i)*g(i)f(i)∗g(i)。

考虑如何求出 g(i)g(i)g(i)。

对于一对父子关系 f(u)=∏(f(son)+1)f(u)=\prod(f(son)+1)f(u)=∏(f(son)+1),其中就有儿子提供的一个贡献 f(v)+1f(v)+1f(v)+1,我们需要去掉。

即,g(v)=g(u)∗∏(f(son)+1)f(v)+1g(v)=g(u)*\frac{\prod(f(son)+1)}{f(v)+1}g(v)=g(u)∗f(v)+1∏(f(son)+1)​。

但是 MMM 并不是质数,所以不能求逆元。

我们可以对每个 uuu 维护出儿子贡献 ∏(f(v)+1)\prod(f(v)+1)∏(f(v)+1) 的前缀积和后缀积。

只要知道某个儿子在其儿子中的编号即可。

具体可见代码实现。

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 100005
vector < int > pre[maxn], suf[maxn];
vector < int > G[maxn];
int f[maxn], g[maxn];
int n, mod;
void dfs1( int u, int fa ) {f[u] = 1;for( int v : G[u] )if( v == fa ) continue;else dfs1( v, u ), f[u] = f[u] * (f[v] + 1) % mod;pre[u].resize( G[u].size() + 1, 1 );suf[u].resize( G[u].size() + 1, 1 );for( int i = 1;i < G[u].size();i ++ ) {pre[u][i] = pre[u][i - 1];if( G[u][i - 1] ^ fa ) pre[u][i] = pre[u][i] * (f[G[u][i - 1]] + 1) % mod;}for( int i = G[u].size() - 2;i >= 0;i -- ) {suf[u][i] = suf[u][i + 1];if( G[u][i + 1] ^ fa )suf[u][i] = suf[u][i] * (f[G[u][i + 1]] + 1) % mod;}
}
void dfs2( int u, int fa ) {for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];if( v == fa ) continue;g[v] = pre[u][i] * suf[u][i] % mod * g[u] % mod + 1;//加1是父亲代表的子树全为白 dfs2( v, u );}
}
signed main() {scanf( "%lld %lld", &n, &mod );for( int i = 1, u, v;i < n;i ++ ) {scanf( "%lld %lld", &u, &v );G[u].push_back( v );G[v].push_back( u );}dfs1( 1, 0 );g[1] = 1;dfs2( 1, 0 );for( int i = 1;i <= n;i ++ ) printf( "%lld\n", g[i] * f[i] % mod );return 0;
}

[AtCoder Educational DP Contest] V - Subtree(树形dp + 前缀积/后缀积)相关推荐

  1. CodeForces - 1324F Maximum White Subtree(树形dp)

    题目链接:点击查看 题目大意:给出 n 个点组成的树,每个点都有一个颜色,非黑即白,现在问对于每个点而言,选出一个连通块,使得白色点的个数与黑色点的个数做差最大 题目分析:记录一下div3的第一次ak ...

  2. 树形dp ---- gym101667 A(贪心 + 树形dp + 两个dp方程组维护)

    题目链接 题目大意: 就是一棵5e35e35e3的树,可以选择一些点,放上基站,如果uuu上的基站价值为ddd,那么距离uuu小于等于ddd的点都会被覆盖,问使得整棵树被覆盖需要的最小价值. 解题思路 ...

  3. 2019 GDCPC or HDU6540 树形dp[计数dp] 详解

    题目链接 题目大意: 就是给你一颗nnn个点的树,树上有mmm个关键点,你可以选择若干个关键点组成集合SSS,这个集合满足任意两点在树上的距离不超过kkk,问你有多少种选法? 解题思路: 我们考虑树形 ...

  4. POJ - 2342 Anniversary party(树形dp入门)

    题目链接:点击查看 题目大意:每个人都有一个快乐值,给定一个树状的从属关系,仅当上司和下属都不在的时候这个个人的快乐值才能表现出来,问怎么样才能让整体的快乐值达到最大 题目分析:做线段树做吐了,来换换 ...

  5. poj 2342 树形DP

    树形DP入门题目. 树形DP说白了就是在搜索的时候动态规划. 只要你懂的深搜+动态规划,就能理解这个基础题了. 先直接搜索到最底层,然后一层一层动态规划,可以说有点像数塔. dp[i][1],dp[i ...

  6. bzoj4472: [Jsoi2015]salesman(树形dp)

    Description 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇 之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收 益.这些净收 ...

  7. 【BZOJ-2435】道路修建 (树形DP?)DFS

    2435: [Noi2011]道路修建 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 3115  Solved: 1002 [Submit][Sta ...

  8. 【CF 543D】Road Improvement,树形DP

    传送门 题意: 给定一棵树,起初树边都是坏边,对于以节点ii为起点,你需要把一些坏边改成好边,使得从ii出发到达其他节点的路径上至多只有一条坏边,求每个节点ii的方案数 思路: 学习了一些新姿势 re ...

  9. E. Xenon's Attack on the Gangs,Codeforces Round #614 (Div. 2),树形dp

    E. Xenon's Attack on the Gangs http://codeforces.com/contest/1293/problem/E On another floor of the ...

最新文章

  1. Yann LeCun:距离“真正的” AI,我们还缺什么?
  2. lr:lr中错误解决方法19种
  3. sqlserver删除指定列失败
  4. python comprehension_python list comprehension在一次迭代中产生两个值
  5. libtool: line 990: g++: command not found的解决
  6. spring data elasticsearch 对应 elasticsearch 版本
  7. 计算机组成原理 第五章 中央处理器
  8. 深圳华为 C++面试题
  9. linux 程序或服务开机自启动
  10. 南航计算机系复试内容,2010年南航计算机专业复试真题
  11. 不想做外包,当不了药神,AI公司如何才能走通制药这条路?
  12. Java的未来前景怎么样?
  13. Zookeeper的事务--Transaction
  14. selenium在爬虫领域的初涉(自动打开网站爬取信息)
  15. 牛牛的旅游纪念品(背包DP)
  16. 【Android多线程】哲学家就餐问题
  17. 基于Docker离线部署开源视频会议系统Jitsi-Meet
  18. 【微信公众号开发】四、公众号按钮设置及自己的微信按钮编辑器
  19. 283页K8S实战指南,内容详实,代码齐全可复制!
  20. ITOP4412 RFID RC522模块

热门文章

  1. 好好珍惜今生,不要期待来世……
  2. 浙江省2021年英语高考成绩查询,浙江高考成绩查询、志愿填报时间公布!
  3. android工程jrr版本怎么改,ionic3 生成android 如何控制versionCode版本号
  4. java io流 教程_Java基础教程:IO流与文件基础
  5. oracle 查看用户状态,Oracle数据库查看用户状态
  6. oracle 动态游标行数,oracle动态游标的简单实现方法
  7. python数据导入hive_Python操作HIve,将数据插入到Mysql
  8. c++向mysql通信_C++连接MySQL
  9. 广西高考成绩查询2021,2021年广西高考个人排名怎么查询,广西高考成绩排名查询方法...
  10. 《C++ Primer》13.1.6节练习(部分)