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

  1. #include <cstdio>
  2. #ifdef ONLINE_JUDGE
  3. #define freopen(a, b, c)
  4. #endif
  5. #define rg register
  6. #define ci const int
  7. #define cl const long long
  8. typedef long long int ll;
  9. namespace IPT {
  10. const int L = 1000000;
  11. char buf[L], *front=buf, *end=buf;
  12. char GetChar() {
  13. if (front == end) {
  14. end = buf + fread(front = buf, 1, L, stdin);
  15. if (front == end) return -1;
  16. }
  17. return *(front++);
  18. }
  19. }
  20. template <typename T>
  21. inline void qr(T &x) {
  22. rg char ch = IPT::GetChar(), lst = ' ';
  23. while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
  24. while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
  25. if (lst == '-') x = -x;
  26. }
  27. template <typename T>
  28. inline void ReadDb(T &x) {
  29. rg char ch = IPT::GetChar(), lst = ' ';
  30. while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
  31. while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
  32. if (ch == '.') {
  33. ch = IPT::GetChar();
  34. double base = 1;
  35. while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
  36. }
  37. if (lst == '-') x = -x;
  38. }
  39. namespace OPT {
  40. char buf[120];
  41. }
  42. template <typename T>
  43. inline void qw(T x, const char aft, const bool pt) {
  44. if (x < 0) {x = -x, putchar('-');}
  45. rg int top=0;
  46. do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
  47. while (top) putchar(OPT::buf[top--]);
  48. if (pt) putchar(aft);
  49. }
  50. const int maxn = 1000010;
  51. const int maxm = 2000010;
  52. const int MOD = 100000007;
  53. struct Edge {
  54. int to, nxt;
  55. };
  56. Edge edge[maxm]; int hd[maxn], ecnt = 1;
  57. inline void cont(ci from, ci to) {
  58. Edge &e = edge[++ecnt];
  59. e.to = to; e.nxt = hd[from]; hd[from] = ecnt;
  60. }
  61. int n, t;
  62. int MU[maxn], frog[maxn], gorf[maxn];
  63. void reading();
  64. void dfs(ci, ci);
  65. int main() {
  66. freopen("1.in", "r", stdin);
  67. qr(n); qr(t);
  68. if (t) {
  69. for (rg int i = 1; i <= n; ++i) MU[i] = i;
  70. } else {
  71. for (rg int i = 1; i <= n; ++i) MU[i] = 1;
  72. }
  73. reading();
  74. dfs(1, 0); qw(frog[1], '\n', true);
  75. return 0;
  76. }
  77. void reading() {
  78. int a, b;
  79. for (rg int i = 1; i < n; ++i) {
  80. a = b = 0; qr(a); qr(b);
  81. cont(a, b); cont(b, a);
  82. }
  83. }
  84. void dfs(ci u, ci pree) {
  85. for (int i = hd[u]; i; i = edge[i].nxt) if (i != pree) {
  86. int &to = edge[i].to;
  87. dfs(to, i ^ 1);
  88. frog[u] = (1ll * frog[to] * gorf[u] % MOD + 1ll * frog[u] * gorf[to] % MOD + frog[to] + frog[u]) % MOD;
  89. gorf[u] = (1ll * gorf[u] * gorf[to] % MOD + gorf[to] + gorf[u]) % MOD;
  90. }
  91. frog[u] = (frog[u] + MU[u]) % MOD;
  92. gorf[u] = (gorf[u] + 1) % MOD;
  93. }

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. Windows10 Oracle ODBC安装配置

    项目紧迫,需在短时间内交付成果,新团队成员,吐嘈之前数据库设计太low,很难看懂数据库表结构间的关系,为了使新同事更好的了解数据库表结构,特意使用powerDesigner对oracle.mysql数 ...

  2. 写一个脚本批量转换项目中GB2312编码的文件为UTF-8编码

    #!/bin/bash convert_file() { for file in `find .` do if [[ -f $file ]] then if [[ ${file##*.} == lua ...

  3. Scrum立会报告+燃尽图(Beta阶段第二周第一次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2409 项目地址:https://coding.net/u/wuyy694 ...

  4. windows环境下nginx服务器的安装与配置

    转载至:http://www.cnblogs.com/hxxy2003/archive/2012/09/20/2695254.html nginx服务器是一个高性能的HTTP和反向代理服务器,它以稳定 ...

  5. SSH新学,关于面向对象的看法

    流程:model-->dao-->service-->impService-->action 如果只是操作单个的一个表,比如user表,则都写到user的流程中 如果要操作俩个 ...

  6. 团队Alpha冲刺(二)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...

  7. 模拟登入教务处(header)

    import HTMLParser import urlparse import urllib import urllib2 import cookielib import string import ...

  8. Eclipse项目导入到Android Studio中

    背景 最近需要将Eclipse中的android项目导入到Android Studio中!倒腾一番,记录如下! 步骤1 打开Android Studio(下文称AS),选择Import project ...

  9. caffe环境搭建笔记

    首先安装以下库或软件 sudo apt-get install gitsudo apt-get install      libprotobuf-dev     libleveldb-dev    l ...

  10. 转 从红帽、GitHub和Docker看开源商业模式的进阶

    从红帽.GitHub和Docker看开源商业模式的进阶 发表于2014-12-16 10:26| 7594次阅读| 来源http://stratechery.com/| 0 条评论| 作者Ben Th ...