月之暗面

[Link](D-月之暗面_牛客练习赛97 (nowcoder.com))

题意

给一颗nnn个结点的数染色,普通染色xxx种,特殊染色yyy种,普通颜色无限制,两个相邻结点不能染相同的特殊颜色

求染色方案数

思路

先按当前结点普通颜色还是特殊颜色来分类,记f[u,0]:以u为根且u填普通颜色的方案数,f[u,1]:以u为根且u填特殊颜色的方案数f[u,0]:以u为根且u填普通颜色的方案数,f[u,1]:以u为根且u填特殊颜色的方案数f[u,0]:以u为根且u填普通颜色的方案数,f[u,1]:以u为根且u填特殊颜色的方案数,互相独立可以相加,关键在于怎么不从不漏的划分方案。

考虑维护方案对于一个点uuu与它相邻的非父亲结点viv_ivi​是相互独立的互不干扰符合乘法原理。

分开来看对于uuu选000子树无限制转移为f[u,0]∗=f[vi,1]+f[vi,0]f[u,0]*=f[v_i,1] +f[v_i,0]f[u,0]∗=f[vi​,1]+f[vi​,0],对于uuu选111的子树当前根会限制这个子树选111的情况,f[vi][1]f[v_i][1]f[vi​][1]中viv_ivi​选111一共yyy种不同颜色,且无本质差别,由于uuu的存在viv_ivi​只能选y−1y-1y−1种颜色,因此转移为f[u,1]∗=f[vi,0]+f[vi,1]×y−1yf[u,1]*=f[v_i,0]+f[v_i,1]\times \frac{y-1}{y}f[u,1]∗=f[vi​,0]+f[vi​,1]×yy−1​

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e6 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 998244353;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
int x, y;
LL f[N][2];
int qmi(int a, int b) {int res = 1;while (b) {if (b & 1) res = (LL) res * a % mod;a = (LL) a * a % mod;b >>= 1;}return res;
}
void dfs(int u, int fa) {f[u][0] = x, f[u][1] = y;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (j == fa) continue ; dfs(j, u);f[u][0] = f[u][0] * (f[j][0] + f[j][1]) % mod; f[u][1] = f[u][1] * (f[j][0] + f[j][1] * k % mod) % mod;}
}
int main() {ios::sync_with_stdio(false), cin.tie(0);cin >> n >> x >> y;memset(h, -1, sizeof h);k = (LL)(y - 1) * qmi(y, mod - 2) % mod;for (int i = 1; i < n; i ++) {int u, v; cin >> u >> v;add(u, v), add(v, u);}dfs(1, -1);cout << (f[1][0] + f[1][1]) % mod << '\n';return 0;
}

因为每个点都要选一种颜色,因此f[u,0]:以u为根且u填了一个普通颜色的方案数,f[u,1]:以u为根且u了一个填特殊颜色的方案数f[u,0]:以u为根且u填了一个普通颜色的方案数,f[u,1]:以u为根且u了一个填特殊颜色的方案数f[u,0]:以u为根且u填了一个普通颜色的方案数,f[u,1]:以u为根且u了一个填特殊颜色的方案数,

则转移时候f[u,0]∗=f[vi,0]∗x+f[vi,1]∗yf[u,0]*=f[v_i,0]*x+f[v_i,1]*yf[u,0]∗=f[vi​,0]∗x+f[vi​,1]∗y,由于uuu选了一个因此viv_ivi​只能选y−1y-1y−1个特殊颜色,所以f[u,1]∗=f[vi,0]∗x+f[vi,1]∗(y−1)f[u,1]*=f[v_i,0]*x+f[v_i,1]*(y-1)f[u,1]∗=f[vi​,0]∗x+f[vi​,1]∗(y−1)

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e6 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 998244353;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
int x, y;
LL f[N][2];
void dfs(int u, int fa) {f[u][0] = 1, f[u][1] = 1;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (j == fa) continue ; dfs(j, u);f[u][0] = (f[u][0] * (f[j][0] * x % mod + f[j][1] * y % mod) % mod) % mod; f[u][1] = (f[u][1] * (f[j][0] * x % mod + f[j][1] * (y - 1)  % mod) % mod) % mod;}}
int main() {ios::sync_with_stdio(false), cin.tie(0);cin >> n >> x >> y;memset(h, -1, sizeof h);for (int i = 1; i < n; i ++) {int u, v; cin >> u >> v;add(u, v), add(v, u);}dfs(1, -1);cout << (f[1][0] * x + f[1][1] * y) % mod << '\n';return 0;
}

月之暗面(树形dp)相关推荐

  1. BNUOJ 52305 Around the World 树形dp

    题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52305 Around the World Time Limit: 20000msMemory ...

  2. [树形dp] Jzoj P5233 概率博弈

    Description 小A和小B在玩游戏.这个游戏是这样的: 有一棵n个点的以1为根的有根树,叶子有权值.假设有m个叶子,那么树上每个叶子的权值序列就是一个1->m 的排列. 一开始在1号点有 ...

  3. fwt优化+树形DP HDU 5909

    1 //fwt优化+树形DP HDU 5909 2 //见官方题解 3 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ 4 5 #include ...

  4. BZOJ 1040 ZJOI2008 骑士 树形DP

    题目大意:给定一个基环树林,每一个点上有权值,要求选择一个权值和最大的点集,要求点集中的随意两个点之间不能直接相连 最大点独立集--考虑到n<=100W,网络流铁定跑不了,于是我们考虑树形DP ...

  5. POJ 3342 树形DP+Hash

    这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算 ...

  6. [NC15748]旅游 树形dp基础

    菜鸡第一次接触树形dp这个东西,不过这个东西还是很好理解的(可能是因为模板题吧) 个人感觉,相比线性dp,树形dp的状态转移方程更加的直观,难点主要是在"树"的结构上比较麻烦. 题 ...

  7. 容斥 + 树形dp ---- 2021 icpc 沈阳 L Perfect Matchings

    题目链接 题目大意: 就是给你一个2n2n2n个点的完全图,从这个图里面抽出2n−12n-12n−1条边,这些边形成一颗树,现在问你剩下的图里面点进行完美匹配有多少种方案? 解题思路: 一开始被完美匹 ...

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

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

  9. 树形dp ---- 2018年杭电多校第二场 H travel

    题目大意: 就是给你一个带点权的树,找到3条独立互不相交的路径使得权值和最大 解题思路: 很经典的树形dp 我们设dp[root][j][k]dp[root][j][k]dp[root][j][k]表 ...

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

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

最新文章

  1. 编译IGSTK5.2
  2. android输出log,Android开发 Release情况下也能输出log
  3. 5年前的Dubbo,2年前的Spring Cloud,都输给了这个架构!
  4. .NET静态类的概念
  5. 为SAP Analytics Cloud的story创建持久化页面
  6. input 中的autoComplete属性
  7. 关于“携号转网” 还有许多你不知道的事
  8. CentOS安装mariadb做为mysql的替代品
  9. BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]
  10. 心情随笔(四):重新审视自我
  11. html video 笔记
  12. 修改Linux里的hosts文件
  13. mtr 检测网络 查看服务器网络是否丢包
  14. 图文介绍:Winhex的使用教程
  15. 峰会倒计时3天!硅谷传奇投资人登陆专场,围炉共话分析型数据库的爆发式增长
  16. 7-1 自动售货机 (30 分)
  17. 滴滴:去年协助警方破获25案件 成立打击黑产专项组
  18. php 完成时钟,PHP 绘制时钟 高洛峰 细说PHP
  19. 在线考勤签到打卡二维码,如何制作?
  20. myeclipse中导入的js文件报错(出现红叉叉,提示语法错误)

热门文章

  1. 乒乓球基本站姿站位和步伐
  2. QT 按钮保持按下时样式
  3. 菜鸟教程php模拟器,史上最强劲的android模拟器命令详解
  4. 深入理解多线程(四)— Moniter的实现原理
  5. MySQL技能树学习体验及期望
  6. Android intent.Action 参数值及对应功能介绍(转)
  7. phpcms 会员头像h5上传_phpcms v9前台会员中心上传头像可getshell及修复
  8. python蓝牙连接测试_基于python实现蓝牙通信代码实例
  9. java语音实现_用JAVA实现语音交互的功能(即语音聊天室的功能)
  10. B860AV2.1盒子刷机