题目简述:给定$n \leq 3 \times 10^5$个节点的树,其中一部分节点被染色,一共有$k$种不同的颜色。求将树划分成 $k$ 个不相交的部分的方案数,使得每个部分中除了未染色的节点以外的所有节点颜色相同,答案模$998244353$(质数)。

解:code

Step 1. 缩点

相关题目:CodeForces 76F. Tourist

观察:为使相同颜色的节点处在同一个子树中,则包含这些节点的最小子树的所有节点必然会被划分在同一部分。

因此,在随意选择一个节点作为树的根节点后,每种颜色的所有节点的LCA(最近公共祖先)必然也与这些节点在同一部分。

同时,我们也得到了无解判定:如果某两种颜色的节点的最小子树具有相同部分,则必定无解。

在判断有解之后,我们可以把每种颜色对应的最小子树缩成一个节点,则问题就转化为:

【一个$n \leq 3\times 10^5$个节点的树,其中有$k$个节点是被标记的,问有多少种方法把树分成$k$部分,每部分包含恰好一个被标记的节点。】

Step 2. 动态规划

我们在缩点之后,只需要解决转化后的问题。

设$f[x][s]$表示以$x$为根的子树有多少种划分方式,使得$x$所在的部分 【未包含$s=0$ / 包含$s=1$】 一个被标记的节点。于是答案为$f[r][1]$,其中$r$是根节点。

1. 若$x$未被标记,则

1.1. 若$x$所在部分未包含被标记的节点,则对每个$x$的儿子节点$y$,若$y$所在部分包含了被标记的节点,则必然不与$x$在同一部分;若$y$所在部分未包含被标记节点,则必然与$x$在同一部分,因此有$f[y][0]+f[y][1]$种可能。由乘法原理,有

$$ f[x][0] = \prod_{y \in \text{son}(x)} (f[y][0]+f[y][1]). $$

1.2. 若$x$所在部分包含被标记的节点,则枚举$x$的儿子节点$y$,其所在部分包含被标记节点,有$f[y][1]$种可能;对其他儿子节点$z \neq y$,若$z$所在部分包含了被标记的节点,则必然不与$x$在同一部分;若$z$所在部分未包含被标记节点,则必然与$x$在同一部分,因此有$f[z][0]+f[z][1]$种可能。由乘法原理和加法原理,有

$$ f[x][1] = \sum_{y \in \text{son}(x)} f[y][1] \prod_{y \neq z \in \text{son}(x)} (f[z][0]+f[z][1]). $$

2. 若$x$被标记,则

2.1. $x$所在部分不可能未包含被标记节点,即

$$ f[x][0] = 0, $$

2.2. 若$x$所在部分包含被标记的节点,则对每个$x$的儿子节点$y$,若$y$所在部分包含了被标记的节点,则必然不与$x$在同一部分;若$y$所在部分未包含被标记节点,则必然与$x$在同一部分,因此有$f[y][0]+f[y][1]$种可能。(这与1.1.的讨论相同)由乘法原理,有

$$ f[x][1] = \prod_{y \in \text{son}(x)} (f[y][0]+f[y][1]). $$

总时间复杂度为$O(n)$。

CodeForces 1118F2. Tree Cutting (Hard Version)的更多相关文章

  1. Codeforces 1118F1 Tree Cutting (Easy Version) (简单树形DP)

    <题目链接> 题目大意: 给定一棵树,树上的点有0,1,2三中情况,0代表该点无色.现在需要你将这棵树割掉一些边,使得割掉每条边分割成的两部分均最多只含有一种颜色的点,即分割后的两部分不能 ...

  2. Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】

    任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per tes ...

  3. Tree Cutting (Hard Version) CodeForces - 1118F2 (树形DP,计数)

    大意:给定树, 每个点有颜色, 一个合法的边集要满足删除这些边后, 每个连通块内颜色仅有一种, 求所有合法边集的个数 $f[x][0/1]$表示子树$x$中是否还有与$x$连通的颜色 对于每种颜色已经 ...

  4. Codeforces Round #540 (Div. 3)--1118F1 - Tree Cutting (Easy Version)

    https://codeforces.com/contest/1118/problem/F1 #include<bits/stdc++.h> using namespace std; in ...

  5. Codeforces 1118 F2. Tree Cutting (Hard Version) 优先队列+树形dp

    题目要求将树分为k个部分,并且每种颜色恰好在同一个部分内,问有多少种方案. 第一步显然我们需要知道哪些点一定是要在一个部分内的,也就是说要求每一个最小的将所有颜色i的点连通的子树. 这一步我们可以将所 ...

  6. 解题:CF1118F2 Tree Cutting (Hard Version)

    题面 好题不问Div(这是Div3最后一题,不得不说Mike真是强=.=) 首先同一个颜色的点的LCA要和它们在一个划分出的块里,那么我们先按颜色把所有点到它们的LCA的路径涂色,如果这个过程中出现了 ...

  7. 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)

    Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...

  8. BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏

    3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 47  Solved: 37[ ...

  9. BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )

    因为是棵树 , 所以直接 dfs 就好了... ---------------------------------------------------------------------------- ...

随机推荐

  1. Android自定义滑动显示隐藏布局

    方式一:上下左右滑动显示隐藏布局 总结代码地址: http://git.oschina.net/anan9303/customView参考例子: http://www.jianshu.com/p/fc ...

  2. PHPCMS替换主页、列表页、内容页

    利用phpcms制作企业站,首先要将静态的企业主页替换成后台可编辑的动态主页. 在phpcms/install_package/phpcms/templates新建一个英文文件夹 在此文件夹下在创建一 ...

  3. 【BZOJ1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap+并查集

    [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000) ...

  4. EasyNVR如何实现跨域鉴权

    EasyNVR提供简单的登录鉴权,客户端通过用户名密码登录成功后,服务端返回认证token的cookie, 后续的接口访问, 服务端从cookie读取token进行校验. 但是, 在与客户系统集成时, ...

  5. async & await (转载)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们 编程埋下了一些 ...

  6. java中随机生成汉字

    main方法中使用: //随机生成100个汉字 String ss=""; for(int i=0;i<100;i++){ ss+=getChinese(i); } Syst ...

  7. C#操作XML方法:新增、修改和删除节点与属性

    一 前言 先来了解下操作XML所涉及到的几个类及之间的关系  如果大家发现少写了一些常用的方法,麻烦在评论中指出,我一定会补上的!谢谢大家 * 1 XMLElement 主要是针对节点的一些属性进行操 ...

  8. SD 相关表

    一.客户主数据基本数据放在KNA1里:公司代码放在KNB1里:销售视图放在KNVV里:合作伙伴放在KNVP里: 二.信用主数据KNKK里有信贷限额.应收总额.特别往来:S066里是未清订单值:S067 ...

  9. 【linux】crontab的环境变量问题

    今天遇到一个奇怪的问题,同样一个脚本,手动执行没问题,加入到crontab中,就出现无法运行的情况,第一反应是环境变量问题 环境说明: 操作系统:centos 用户:test用户通过sudo su切换 ...

  10. python多进程编程常用到的方法

    python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU资源,在python中大部分情况需要使用多进程.python提供了非常好用的多进程包Multiprocessing,只需要定义 ...