独钓寒江雪

题目链接https://www.lydsy.com/JudgeOnline/problem.php?id=3162


题解

首先,如果没有那个本质相同的限制这就是个傻逼题。

直接树形dp就好。

那么如果加上那个限制呢?

我们发现,无论最后怎么本质相同,树的重心一定不变。

故此,从重心开始去重即可。

参考:https://www.cnblogs.com/zhoushuyu/p/9295759.html

代码

  1. #include <bits/stdc++.h>
  2.  
  3. #define N 500010
  4.  
  5. using namespace std;
  6.  
  7. const int mod = 1000000007 ;
  8.  
  9. char *p1, *p2, buf[100000];
  10.  
  11. typedef unsigned long long ll;
  12.  
  13. ll bs1 = 20021214 ;
  14.  
  15. ll bs2 = 20030315 ;
  16.  
  17. #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
  18.  
  19. int rd() {
  20. int x = 0;
  21. char c = nc();
  22. while (c < 48) {
  23. c = nc();
  24. }
  25. while (c > 47) {
  26. x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
  27. }
  28. return x;
  29. }
  30.  
  31. int n, inv[N], to[N << 1], nxt[N << 1], head[N], tot, sz[N], w[N], root, rt1, rt2, flag, f[2][N], tmp[N];
  32.  
  33. ll hs[N];
  34.  
  35. inline void add(int x, int y) {
  36. to[ ++ tot] = y;
  37. nxt[tot] = head[x];
  38. head[x] = tot;
  39. }
  40.  
  41. void getroot(int p, int fa) {
  42. sz[p] = 1;
  43. w[p] = 0;
  44. for (int i = head[p]; i; i = nxt[i]) {
  45. if(to[i] != fa) {
  46. getroot(to[i], p);
  47. sz[p] += sz[to[i]];
  48. w[p] = max(w[p], sz[to[i]]);
  49. }
  50. }
  51. w[p] = max(w[p], n - sz[p]);
  52. if (w[p] < w[root]) {
  53. root = p;
  54. }
  55. }
  56.  
  57. int C(int n, int m) {
  58. int re = 1;
  59. for (int i = n - m + 1; i <= n; i ++ ) {
  60. re = (ll)re * i % mod;
  61. }
  62. for (int i = 1; i <= m; i ++ ) {
  63. re = (ll)re * inv[i] % mod;
  64. }
  65. return re;
  66. }
  67.  
  68. inline bool cmp(int i, int j) {
  69. return hs[i] < hs[j];
  70. }
  71.  
  72. void dfs(int p, int fa) {
  73. sz[p] = f[0][p] = f[1][p] = 1;
  74. for (int i = head[p]; i; i = nxt[i]) {
  75. if (to[i] != fa) {
  76. dfs(to[i], p);
  77. sz[p] += sz[to[i]];
  78. }
  79. }
  80. int len = 0;
  81. for (int i = head[p]; i; i = nxt[i]) {
  82. if (to[i] != fa) {
  83. tmp[ ++ len] = to[i];
  84. }
  85. }
  86. sort(tmp + 1, tmp + len + 1, cmp);
  87. for (int i = 1, j = 1; i <= len; i = j) {
  88. while (j <= len && hs[tmp[j]] == hs[tmp[i]]) {
  89. j ++ ;
  90. }
  91. f[0][p] = (ll)f[0][p] * C(f[0][tmp[i]] + f[1][tmp[i]] + j - i - 1, j - i) % mod;
  92. f[1][p] = (ll)f[1][p] * C(f[0][tmp[i]] + j - i - 1, j - i) % mod;
  93. }
  94. hs[p] = bs2 * len + sz[p];
  95. for (int i = 1; i <= len; i ++ ) {
  96. hs[p] = (hs[p] * bs1) ^ hs[tmp[i]];
  97. }
  98. }
  99.  
  100. int main() {
  101. n = rd();
  102. inv[0] = inv[1] = 1;
  103. for (int i = 2; i <= n; i ++ ) {
  104. inv[i] = (ll)inv[mod % i] * (mod - mod / i) % mod;
  105. }
  106. for (int i = 1; i < n; i ++ ) {
  107. int x = rd(), y = rd();
  108. add(x, y), add(y, x);
  109. }
  110. w[0] = n;
  111. getroot(1, 0);
  112. getroot(root, 0);
  113. for (int i = head[root], last = 0; i; last = i, i = nxt[i]) {
  114. if (sz[to[i]] * 2 == n) {
  115. n ++ ;
  116. if (i == head[root]) {
  117. head[root] = nxt[i];
  118. }
  119. else {
  120. nxt[last] = nxt[i];
  121. }
  122. for (int j = head[to[i]], lst = 0; j; lst = j, j = nxt[j]) {
  123. if (to[j] == root) {
  124. if (j == head[to[i]]) {
  125. head[to[i]] = nxt[j];
  126. }
  127. else {
  128. nxt[lst] = nxt[j];
  129. }
  130. break;
  131. }
  132. }
  133. add(n, root);
  134. add(root, n);
  135. add(n, to[i]);
  136. add(to[i], n);
  137. rt1 = root;
  138. rt2 = to[i];
  139. root = n;
  140. flag = 1;
  141. break;
  142. }
  143. }
  144. dfs(root, 0);
  145. if (!flag) {
  146. cout << (f[0][root] + f[1][root]) % mod << endl ;
  147. }
  148. else if (hs[rt1] == hs[rt2]) {
  149. cout << (f[0][root] - C(f[1][rt1] + 1, 2) + mod) % mod;
  150. }
  151. else {
  152. cout << ((ll)f[0][rt1] * f[0][rt2] + (ll)f[0][rt1] * f[1][rt2] + (ll)f[1][rt1] * f[0][rt2]) % mod << endl ;
  153. }
  154. }

小结:树hash的时候,如果一个模数担心过不去,像我一样开两个就好了233

[bzoj3162]独钓寒江雪_树hash_树形dp的更多相关文章

  1. BZOJ3162 独钓寒江雪(哈希+树形dp)

    数独立集显然是可以树形dp的,问题在于本质不同. 假设已经给树确立了一个根并且找到了所有等效(注意是等效而不是同构)子树,那么对转移稍加修改使用隔板法就行了. 关键在于找等效子树.首先将树的重心(若有 ...

  2. BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP

    BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP Description Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的 ...

  3. BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP

    BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T ...

  4. 【NOI P模拟赛】仙人掌(圆方树,树形DP)

    题面 n n n 个点, m m m 条边. 1 ≤ n ≤ 1 0 5 , n − 1 ≤ m ≤ 2 × 1 0 5 1\leq n\leq 10^5,n-1\leq m\leq 2\times1 ...

  5. bzoj 1040 [ZJOI2008]骑士(基环外向树,树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题意] 给一个基环森林,每个点有一个权值,求一个点集使得点集中的点无边相连且权 ...

  6. 洛谷4895 独钓寒江雪 (树哈希+dp+组合)

    qwq 首先,如果是没有要求本质不同的话,那么还是比较简单的一个树形dp 我们令\(dp[i][0/1]\)表示是否\(i\)的子树,是否选\(i\)这个点的方案数. 一个比较显然的想法. \(dp[ ...

  7. 青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

    题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 ...

  8. 洛谷AT2046 Namori(思维,基环树,树形DP)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...

  9. Luogu4630 APIO2018 Duathlon 圆方树、树形DP

    传送门 要求的是一条按顺序经过\(s,t,c\)三个点的简单路径.简单路径的计数问题不难想到点双联通分量,进而使用圆方树进行求解. 首先将原图缩点,对于一个大小为\(size\)的点双联通分量内,在这 ...

随机推荐

  1. 013_STM32程序移植之_DS18B20

    013_STM32程序移植之_DS18B20 1. 测试环境:STM32C8T6 2. 测试模块:DS18B20模块 3. 测试接口: 1. DS18B20模块接口: DS18B20引脚        ...

  2. JVM(十),垃圾回收之新生代垃圾收集器

    十.垃圾回收之新生代垃圾收集器 1.JVM的运行模式 2.Serial收集器(复制算法-单线程-Client模式) 2.ParNew收集器(复制算法-多线程-Client模式) 3.Parallel ...

  3. DP-------bzoj2699 更新

    题目描述: 对于一个数列A[1..N],一种寻找最大值的方法是:依次枚举A[2]到A[N],如果A[i]比当前的A[1]值要大,那么就令A[1]=A[i],最后A[1]为所求最大值.假设所有数都在范围 ...

  4. tomcat使用实践三种运行模式之apr

    tomcat有三种运行模式 nio,bio,apr bio是阻塞式IO操作,使用的是传统的java i/o处理方式,对于每一个请求都要创建一个线程来进行处理,所以开销较大不适合处理高并发的场景 nio ...

  5. 关于Linux上面无法读取资源目录下文件的问题

    一开始我的代码是这样子的,读取本地子路径下的json文件 代码运行的时候,在window是可以正常的 @Override public String getBannerStr() { String s ...

  6. vsftp的安装和使用

    检查Linux系统是否安装了vsftpd的命令: rpm -qa|grep vsftpd 2.安装命令: yum -y install vsftpd 3.卸载命令: yum remove vsftpd ...

  7. 0ctf-ezdoor-复现分析

    在学习opcache的时候,看到了这个题目,刚好有环境,就来复现一下,这个题目也让我学到了很多. 创建镜像: docker build -t 0ctf-ezdoor . 启动容器: docker ru ...

  8. Vue入门下

    使用npm创建项目,系统会自动生成一些列文件. 以慕课网上的Travel项目来说,在生成的项目文件中存在src文件夹,这个文件夹也是平时在做项目的时候用的比较多的,其他的一些配置信息更改的频率较低. ...

  9. hadoop用户和权限

    当前Apache Hadoop认证(authentication)支持simple和kerberos,simple是默认的,其实是信任操作系统的认证结果(也就是直接使用操作系统的用户).kerbero ...

  10. 埃利斯(A.Ellis)ABCDE情绪管理理论

    埃利斯(A.Ellis)ABCDE情绪管理理论A :Activating Events(诱发事件)B :Beliefs(个体对诱发事件的评价.解释.看法)C :Consequences(个体情绪和行为 ...