Description

给定一棵以 1 为根的有根树,定义树的一个毒瘤集为一个集合,并且集合中任意两个元素之间不存在祖先与后代关系。

定义一个毒瘤集的毒瘤指数为集合内所有元素的价值之和

要求给定树的所有毒瘤集的毒瘤指数之和,答案对 100000007 取模。

但这个问题太难了,所以我们考虑化简。

因为点的编号跟它毒瘤指数密切相关,所以我们将会再给出一个整数 T,T = 1 表示 i 号点的毒瘤指数为 i,T = 0,表示所有点的毒瘤指数都是 1

Input

第一行两个整数 n、T,表示这棵树有 n 个节点。

接下来 n -1 行,每行两个整数 x 和 y,表示有一条边,连接 x 和 y。

Output

输出一个整数,表示答案。

Hint

\(Forall:\)

\(0~\leq~n~\leq~10^6~,~T~\leq~1\)

Solution

数数题,考虑DP。

设\(f_u\)是以\(u\)为根的子树,先考虑 \(T~=~0\) 的情况

当点\(u\)只有两个儿子 \(v_1~,~v_2\) 的时候,显然 \(f_u~=~f_{v_1}~+~f_{v_2}~+~f_{v_1}~\times~f_{v_2}~+~1\)

考虑\(u\)有多个儿子的时候也类似,设 \(g_j\) 为考虑点 \(u\) 的前\(j\)个子树的集合数,于是

\(g_j~=~g_{j-1}~\times~f_v~+~g_j~+~f_v\)

考虑 \(T~\neq~0\) 的情况

设 \(f_u\) 为以 \(u\) 为根的ans,\(g_u\) 为以 \(u\) 为根的集合个数

\[f_u~=~f_v~\times~g_u~+~f_u~\times~g_v~+~f_u~+f_v
\]

\[g_u~=~g_u~+~g_v~+~g_u~\times~g_v
\]

复杂度 \(O(n)\) 。听说有人用nlogn水过去了?

Code

#include <cstdio>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
#define rg register
#define ci const int
#define cl const long long typedef long long int ll; namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
} template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
} template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
} namespace OPT {
char buf[120];
} template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
} const int maxn = 1000010;
const int maxm = 2000010;
const int MOD = 100000007; struct Edge {
int to, nxt;
};
Edge edge[maxm]; int hd[maxn], ecnt = 1;
inline void cont(ci from, ci to) {
Edge &e = edge[++ecnt];
e.to = to; e.nxt = hd[from]; hd[from] = ecnt;
} int n, t;
int MU[maxn], frog[maxn], gorf[maxn]; void reading();
void dfs(ci, ci); int main() {
freopen("1.in", "r", stdin);
qr(n); qr(t);
if (t) {
for (rg int i = 1; i <= n; ++i) MU[i] = i;
} else {
for (rg int i = 1; i <= n; ++i) MU[i] = 1;
}
reading();
dfs(1, 0); qw(frog[1], '\n', true);
return 0;
} void reading() {
int a, b;
for (rg int i = 1; i < n; ++i) {
a = b = 0; qr(a); qr(b);
cont(a, b); cont(b, a);
}
} void dfs(ci u, ci pree) {
for (int i = hd[u]; i; i = edge[i].nxt) if (i != pree) {
int &to = edge[i].to;
dfs(to, i ^ 1);
frog[u] = (1ll * frog[to] * gorf[u] % MOD + 1ll * frog[u] * gorf[to] % MOD + frog[to] + frog[u]) % MOD;
gorf[u] = (1ll * gorf[u] * gorf[to] % MOD + gorf[to] + gorf[u]) % MOD;
}
frog[u] = (frog[u] + MU[u]) % MOD;
gorf[u] = (gorf[u] + 1) % MOD;
}

Summary

这是一类非常经典的求树上方案数的题目,一般这类题目的解决方法是使用另一个数组表示“当前已经枚举到的”某些值,每枚举一个儿子单独计算贡献。

【DP】【P5007】 DDOSvoid 的疑惑的更多相关文章

  1. luogu5007 DDOSvoid 的疑惑 (树形dp)

    我们来算每个点出现在的集合的个数 设f[i]为i出现的集合个数,g[i]是只选子树i 可以有多少种选法 那就有$g[i]=1+\prod\limits_{j是i的孩子}{g[j]} , f[i]=f[ ...

  2. 【DP】【CF855C】 Helga Hufflepuff's Cup

    Description 给你一个树,可以染 \(m\) 个颜色,定义一个特殊颜色 \(k\) , 要求保证整棵树上特殊颜色的个数不超过 \(x\) 个.同时,如果一个节点是特殊颜色,那么它的相邻节点的 ...

  3. zzulioj--1719--小胖的疑惑(整数划分+dp打表)

    1719: 小胖的疑惑 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 108  Solved: 51 SubmitStatusWeb Board De ...

  4. 【CSP模拟】小凯的疑惑(DP)

    首先,这道题正解的思路是从subtask2而得来的,所以先讲一下subtask2的做法. 因为保证答案不超过long long,所以直接求最大权独立集即可:dp[u][0]表示u点一定不能取的答案,d ...

  5. dp和px,那些不得不吐槽的故事——Android平台图

    http://blog.sina.com.cn/s/blog_6499f8f101014ipq.html 一个优秀的手机软件,不仅要有精巧的功能,流畅的速度,让人赏心悦目的UI也往往是用户选择的重要理 ...

  6. 洛谷P1021邮票面值设计 [noip1999] dp+搜索

    正解:dfs+dp 解题报告: 传送门! 第一眼以为小凯的疑惑 ummm说实话没看标签我还真没想到正解:D 本来以为这么多年前的noip应该不会很难:D 看来还是太菜了鸭QAQ 然后听说题解都可以被6 ...

  7. 洛谷 P1140 相似基因(DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://www.cnblogs.com/real-l/p/9 ...

  8. dp和px,那些不得不吐槽的故事——Android平台图片文字元素单位浅析 (转)

    一个优秀的手机软件,不仅要有精巧的功能,流畅的速度,让人赏心悦目的UI也往往是用户选择的重要理由.作为移动产品的PM,也需要了解一些在UI设计中的基本知识. 1. px和pt,一对好伙伴 在视觉设计中 ...

  9. HDU-6156 Palindrome Function(数位DP)

    一.题目 二.思路 1.这是很明显的数位DP: 2.和以往数位DP不同的是,这里带了个进制进来,而以往做是纯十进制下或者纯二进制下做操作.但是,不管多少进制,原理都是一样的: 3.这里有个小坑,题目中 ...

随机推荐

  1. Jupyter 安装并配置工作路径[转]

    1.通过python的pip方式安装jupyterpython和pip都安装好后,通过cmd进入命令提示窗口,找到python安装目录下的Script目录,例如我的是路径是:C:\Program Fi ...

  2. 445. Cosine Similarity【LintCode java】

    Description Cosine similarity is a measure of similarity between two vectors of an inner product spa ...

  3. mongodb4简明笔记

    就一数据库,掌握基本用法,其他的现学现卖就行了. 所以要把握基本套路. 创建数据库=>使用数据库=>创建集合=>使用集合=>创建文档=>使用文档 1.数据库 mongod ...

  4. 01_基于TCP的循环为同一个客户端下载文件的下载器

    原版: TCP分为客户端(client)和服务器(server),每次服务器只能为客户端提供一次的下载服务. 改良版: TCP分为客户端(client)和服务器(server), (1)每次服务器能为 ...

  5. Halcon算子解释

    Halcon算子解释大全 Halcon/Visionpro视频教程和资料,请访问 重码网,网址: http://www.211code.com Chapter 1 :Classification 1. ...

  6. Windows下使用WinRAR命令自动备份文件

    最近有一个需求:为了防止数据丢失,每天对固定文件夹下的文件进行打包压缩备份. 解决办法:使用Windows的任务计划程序,每天执行一下压缩命令: Windows任务计划程序在这里就不再介绍了,网上有很 ...

  7. ES6的新特性(20)—— Module 的加载实现

    Module 的加载实现 上一章介绍了模块的语法,本章介绍如何在浏览器和 Node 之中加载 ES6 模块,以及实际开发中经常遇到的一些问题(比如循环加载). 浏览器加载 传统方法 HTML 网页中, ...

  8. 7. B+树

    一.B+树是应文件系统所需而产生的一种B树的变形树 1. 定义(使用阶数m来定义) 除了根结点外,其他非终端结点最多有m个关键字,最少有⌈m/2⌉个关键字 结点中的每个关键字对应一个子树 所有的非终端 ...

  9. 使用JSon实现三级联动

    JSon实现三级联动 我觉得我这个方法比较麻烦,但是目前技术还比较弱,所以先做个笔记自己理解.目前没有和后台交互,只是在前台页面实现了 jQuery和JSon数据实现的,代码如下: <!DOCT ...

  10. HDU 5207 Greatest Greatest Common Divisor

    题目链接: hdu:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=153598 bc(中文):http://bestco ...