CF1146F - Leaf Partition(树形dp)

CF1146F - Leaf Partition

Solution

感觉做这种细节很多的分类讨论树形dp还是有点乱。

大概有一个naivenaivenaive的想法是,我们令fx,0/1f_{x,0/1}fx,0/1表示以xxx为根的子树,xxx结点有没有颜色的方案数。

然后如果存在两个有颜色的儿子,则xxx的颜色可以直接确定。

但是直接这样不好转移(因为当前无色的点可能在更浅的地方和其他点连通导致有了颜色),我们修改状态为fx,0/1/2f_{x,0/1/2}fx,0/1/2000表示xxx无色,111表示我们钦定了xxx为一种它儿子的颜色,222表示xxx有一种确定的颜色。

那么
fx,0=∏vfv,0+fv,2fx,1=(∏vfv,0+fv,2)(∑vfv,2fv,0+fv,2)+(∏vfv,0+fv,2)(∑vfv,1fv,0+fv,2)fx,2=(∏vfv,0+fv,1+fv,2+fv,2)−(∏vfv,0+fv,2)−(∏vfv,0+fv,2)(∑vfv,1+fv,2fv,0+fv,2)f_{x,0}=\prod_v{f_{v,0}+f_{v,2}}\\ f_{x,1}=(\prod_v{f_{v,0}+f_{v,2})(\sum_v{\frac{f_{v,2}}{f_{v,0}+f_{v,2}}}})+(\prod_v{f_{v,0}+f_{v,2})(\sum_v{\frac{f_{v,1}}{f_{v,0}+f_{v,2}}}})\\ f_{x,2}=(\prod_v{f_{v,0}+f_{v,1}+f_{v,2}+f_{v,2})-(\prod_v{f_{v,0}+f_{v,2}})-(\prod_v{f_{v,0}+f_{v,2}})(\sum_v{\frac{f_{v,1}+f_{v,2}}{f_{v,0}+f_{v,2}}}})fx,0=vfv,0+fv,2fx,1=(vfv,0+fv,2)(vfv,0+fv,2fv,2)+(vfv,0+fv,2)(vfv,0+fv,2fv,1)fx,2=(vfv,0+fv,1+fv,2+fv,2)(vfv,0+fv,2)(vfv,0+fv,2)(vfv,0+fv,2fv,1+fv,2)

时间复杂度O(nlgn)O(nlgn)O(nlgn)(快速幂)。

Code

#include <bits/stdc++.h>using namespace std;template<typename T> inline bool upmin(T &x, T y) { return y <= x ? x = y, 1 : 0; }
template<typename T> inline bool upmax(T &x, T y) { return x <= y ? x = y, 1 : 0; }#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondtypedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int, int> PR;
typedef vector<int> VI; const lod eps = 1e-9;
const lod pi = acos(-1);
const int oo = 1 << 30;
const ll loo = (1ll << 62) - 1;
const int MAXN = 200005;
const int mods = 998244353;
const int MX = 100000;
const int inv2 = (mods + 1) >> 1;
const int INF = 0x3f3f3f3f; //1061109567
/*--------------------------------------------------------------------*/namespace FastIO{constexpr int SIZE = (1 << 21) + 1;int num = 0, f;char ibuf[SIZE], obuf[SIZE], que[65], *iS, *iT, *oS = obuf, *oT = obuf + SIZE - 1, c;#define gc() (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)), (iS == iT ? EOF : *iS ++)) : *iS ++)inline void flush() {fwrite(obuf, 1, oS - obuf, stdout);oS = obuf;}inline void putc(char c) {*oS ++ = c;if (oS == oT) flush();}inline void getc(char &c) {for (c = gc(); !isalpha(c) && c != EOF; c = gc());}inline void reads(char *st) {char c;int n = 0;getc(st[++ n]);for (c = gc(); isalpha(c) ; c = gc()) st[++ n] = c;st[++ n] = '\0';}template<class I>inline void read(I &x) {for (f = 1, c = gc(); c < '0' || c > '9' ; c = gc()) if (c == '-') f = -1;for (x = 0; c >= '0' && c <= '9' ; c = gc()) x = (x << 3) + (x << 1) + (c & 15);x *= f;}template<class I>inline void print(I x) {if (x < 0) putc('-'), x = -x;if (!x) putc('0');while (x) que[++ num] = x % 10 + 48, x /= 10;while (num) putc(que[num --]);}inline void putstr(string st) {for (int i = 0; i < (int)st.size() ; ++ i) putc(st[i]);}struct Flusher_{~Flusher_(){flush();}} io_Flusher_;
}
using FastIO :: read;
using FastIO :: putc;
using FastIO :: putstr;
using FastIO :: reads;
using FastIO :: print;int f[MAXN][3];
vector<int> e[MAXN];
int upd(int x, int y) { return x + y >= mods ? x + y - mods : x + y; }
int quick_pow(int x, int y) {int ret = 1;for (; y ; y >>= 1) {if (y & 1) ret = 1ll * ret * x % mods;x = 1ll * x * x % mods;}return ret;
}
void tree_dp(int x) {for (auto v : e[x]) tree_dp(v);if (!e[x].size()) { f[x][0] = f[x][1] = 0, f[x][2] = 1; return; }f[x][0] = 1;int mul = 1, Mul = 1, sum = 0;for (auto v : e[x]) {f[x][0] = 1ll * f[x][0] * upd(f[v][0], f[v][2]) % mods;f[x][1] = upd(f[x][1], 1ll * upd(f[v][1], f[v][2]) * quick_pow(upd(f[v][0], f[v][2]), mods - 2) % mods);int t = upd(f[v][0], f[v][2]), invt = quick_pow(t, mods - 2);mul = 1ll * mul * t % mods;Mul = 1ll * Mul * upd(upd(f[v][0], f[v][1]), upd(f[v][2], f[v][2])) % mods;sum = upd(sum, 1ll * invt * upd(f[v][1], f[v][2]) % mods);}f[x][1] = 1ll * f[x][1] * f[x][0] % mods;f[x][2] = upd(Mul, mods - upd(mul, 1ll * mul * sum % mods));
//	cout << x << ":" << e[x].size() << " " << mul << " " << Mul << " " << sum << " " << f[x][0] << " " << f[x][1] << " " << f[x][2] << endl;
}
signed main() {
#ifndef ONLINE_JUDGEfreopen("a.in", "r", stdin);
#endif	int n;read(n);for (int i = 2, x; i <= n ; ++ i) read(x), e[x].PB(i);tree_dp(1);print(upd(f[1][0], f[1][2]));return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源基于Canal的开源增量数据订阅消费中间件

canal 是阿里巴巴开源的一款基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB)。我开发的这个CanalSync项目 https://github.com/yuzd/CanalSync >觉得不错帮忙给个star谢谢是基于canal-server之上的数据库同步&消费中间件&#…

E2. Square-free division (hard version) dp + 质因子分解

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你长度为nnn的数组&#xff0c;让后最多修改其中kkk个数(可以修改为任意数)&#xff0c;让后问你分成的最少组是多少。这个组内元素是连续的且不存在任意两个数的积为平方数。 思路&#xff1a; 首先两个…

CF1000G. Two-Paths(树形dp)

CF1000G. Two-Paths Solution 我们发现除了树上(x,y)(x,y)(x,y)最短路径上的边经过一次&#xff0c;其余边要么走000次&#xff0c;要么走222次。 因此考虑先假设每条边走两次&#xff0c;最后把走一次的边的贡献加上。 我们把从(x,y)(x,y)(x,y)路径上的点扩展出去连痛块的…

不装 VS 自己编译安装 Windows Terminal

Windows Terminal 一直没有发布可以直接安装的二进制文件&#xff0c;想自行编译的时候&#xff0c;看到系统需求中包含体积巨大的 Visual Studio 和 Windows SDK&#xff0c;脑袋都大了。直接下载其他人编译好的安装包又不放心&#xff0c;那么就想个办法避免在本地环境编译吧…

Codeforces Round #604 (Div. 2) E. Beautiful Mirrors 期望dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 要从111走到nnn&#xff0c;每次成功走下去的概率为pi100\frac{p_i}{100}100pi​​&#xff0c;如果不成功那就回到111号点继续走。问走完nnn个点的期望是多少。 思路&#xff1a; 以前见过这种失败了就回…

带你了解C#每个版本新特性

上学时学习C#和.NET&#xff0c;当时网上的资源不像现在这样丰富&#xff0c;所以去电脑城买了张盗版的VS2005的光盘&#xff0c;安装时才发现是VS2003&#xff0c;当时有一种被坑的感觉&#xff0c;但也正是如此&#xff0c;让我有了一个完整的.NET的学习生涯。一直都认为学习…

Educational Codeforces Round 106 (Rated for Div. 2) D. The Number of Pairs 数论gcd

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给三个数c,d,xc,d,xc,d,x&#xff0c;求满足c∗lcm(a,b)−d∗gcd(a,b)xc*lcm(a,b)-d*gcd(a,b)xc∗lcm(a,b)−d∗gcd(a,b)x条件的(a,b)(a,b)(a,b)的数量。 思路&#xff1a; 考虑将lcm(a,b)lcm(a,b)lcm(a,b…

从零开始制作 NuGet 源代码包(全面支持 .NET Core / .NET Framework / WPF 项目)

默认情况下&#xff0c;我们打包 NuGet 包时&#xff0c;目标项目安装我们的 NuGet 包会引用我们生成的库文件&#xff08;dll&#xff09;。除此之外&#xff0c;我们也可以专门做 NuGet 工具包&#xff0c;还可以做 NuGet 源代码包。然而做源代码包可能是其中最困难的一种了&…

HDU - 4497 GCD and LCM 数论gcd

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给三个数的lcmlcmlcm和gcdgcdgcd&#xff0c;求满足条件的三元组组合个数。 思路&#xff1a; 首先lcmmodgcd0lcm\bmod gcd0lcmmodgcd0是有组合的条件&#xff0c;否则输出0。 现在可知lcm(x′,y′,z′)lc…

.NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新

我们都知道在6月12日的时候微软发布了.NET Core 3.0的第6个预览版。针对.NET Core 3.0的发布我们国内的微软MVP-汪宇杰还发布的官翻版的博文进行了详细的介绍。具体的可以点这里进行阅读译 | .NET Core 3.0 Preview 6 已发布。而我们这篇文章将会介绍本次更新中对ASP.NET Core和…

Codeforces Round #686 (Div. 3) F. Array Partition 二分 + 线段树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 化简一下题意就是求满足max(1,x)min(x1,y)max(y1,n)max(1,x)min(x1,y)max(y1,n)max(1,x)min(x1,y)max(y1,n)的len1x,len2y−x,len3n−ylen1x,len2y-x,len3n-ylen1x,len2y−x,len3n−y。 思路&#xff1a; …

Dapper.Common基于Dapper的开源LINQ超轻量扩展

Dapper.CommonDapper.Common是基于Dapper的LINQ实现,支持.net core,遵循Linq语法规则、链式调用、配置简单、上手快,支持Mysql,Sqlserver(目前只实现了这两个数据库&#xff0c;实现其他数据库也很轻松)&#xff0c;支持单表&#xff0c;多表&#xff0c;自定义函数等功能。源码…

Codeforces Round #686 (Div. 3) E. Number of Simple Paths 基环树 + 容斥

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一颗基环树&#xff0c;求长度>1>1>1的路径个数。 思路&#xff1a; 先考虑一棵树&#xff0c;他的答案显然是n∗(n−1)2\frac{n*(n-1)}{2}2n∗(n−1)​。因为是个基环树&#xff0c;所以先考…

.NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖

我们有多种工具可以将程序集合并成为一个。比如 ILMerge、Mono.Merge。前者不可定制、运行缓慢、消耗资源&#xff08;不过好消息是现在开源了&#xff09;&#xff1b;后者已被弃用、不受支持且基于旧版本的 Mono.Cecil。而本文介绍用来替代它们的 ILRepack&#xff0c;使用 I…

4G的小程序与5G的Chromium OS?

提到桌面操作系统&#xff0c;Windows 与 macOS 自然是家喻户晓&#xff0c;稍微有点 IT 知识的人也会知道 Linux&#xff0c;而 Fuchsia 和鸿蒙&#xff08;方舟&#xff09;则还在积极开发中&#xff0c;除了这几大类比较热门的&#xff0c;当前还有一大潜力股 Chrome OS&…

Codefest 18 (rated, Div. 1 + Div. 2)-D-Valid BFS--思维--已知bfs序,求是否正确

Codefest 18 (rated, Div. 1 Div. 2)-D-Valid BFSvj地址 题意&#xff1a;给你一段bfs序列&#xff0c;让你判断是否正确 思路&#xff1a;先给节点排序&#xff08;很关键&#xff09; 我们给每一个的点的邻接表按照给出的bfs序列排序&#xff0c;排好后&#xff0c; 我跑一…

P3605 [USACO17JAN]Promotion Counting P dfs序

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 这个题可以用各种姿势a掉&#xff0c;树启和线段树合并都可以&#xff0c;比较无脑。下面给一个解决这种问题比较巧妙的做法。 考虑暴力怎么写&#xff0c;我们先将每个点的权值离散化一下…

推荐VSCode多语言开发,支持一键JAVA

哈喽大家周一好&#xff01;好久不见鸭&#xff0c;最近在看一本书&#xff0c;很好&#xff0c;《人类简史》&#xff0c;适合夏日星空&#xff0c;仰观宇宙之大?这个专题是“做贡献”&#xff0c;也是作为软粉&#xff0c;打算一直推广微软自己的东西&#xff0c;上一次还是…

思维--找规律--Codeforces Round #645 (Div. 2) c题

C. Celex Update 题目大意&#xff1a;给出两点的坐标&#xff0c;找出不同的路径的总数&#xff08;路径数字总和不同&#xff09; 思路&#xff1a;根据观察向下走比向右走的增加幅度加1&#xff0c;所以在第i步 向下 对sum的影响是 n-i1 所以最小数字为12。。。。y&#xf…

Codeforces Round #709 (Div. 1, based on Technocup 2021 Final Round) A. Basic Diplomacy

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 有nnn个小朋友&#xff0c;让后你要在mmm天中每天都选择一个小朋友&#xff0c;给出这mmm天都可以选哪个小朋友&#xff0c;每个小朋友选的次数不超过⌈m2⌉\left \lceil \frac{m}{2} \right \rceil⌈2m​⌉…