SRM 682 Div2 1000 SubtreesCounting
2016-03-03 18:35
369 查看
题面:定义一个树的value为树的所有联通子图的节点数之和
求给出的一个树的value
感觉很巧妙的一个树dp
因为是一个无根树,不妨把0号节点提起来作为根,记Tx为以x为根节点的子树
定义 Sx为在Tx中选择x的value (然后答案就是∑x:树上所有的节点Sx)
定义Cx为在Tx中选择x的联通子图的个数
考虑两个树,分别以st和x为根,而且分别计算出了他们各自的S和C的值
那么,将x连到st上作为st的子节点时,考虑更新的Sst的变化,为了区别,记更新后的Cst和Sst分别为Croot和Sroot
先考虑简单的,Croot的值,如果不选x,那么方案数不变,如果选x,那么每一个原来的方案数都可以对应着Cx种方案数,合并一下就是Cst+Cst×Cx=Cst×(Cx+1)
对于Sroot的值,同样考虑是否选择x,如果不选择,那么对Sroot的贡献还是Sst,也就是原来的方案
如果选择了x,情况稍微复杂一点,分别考虑Tst和Tx
对于Tst上的点的贡献
每一个值为Sst的方案都对应着Cx次贡献,所以对Sroot的贡献为 Cx×Sst
对于Tx上的点
同样的,每一个值为Sx一个方案都对应着Cst次贡献,所以对Sroot的贡献为Cst×Sc
所以,Sroot=Sst+Cx×Sst+Cst×Sc=(1+Cx)×Sst+Cst×Sc
求给出的一个树的value
感觉很巧妙的一个树dp
因为是一个无根树,不妨把0号节点提起来作为根,记Tx为以x为根节点的子树
定义 Sx为在Tx中选择x的value (然后答案就是∑x:树上所有的节点Sx)
定义Cx为在Tx中选择x的联通子图的个数
考虑两个树,分别以st和x为根,而且分别计算出了他们各自的S和C的值
那么,将x连到st上作为st的子节点时,考虑更新的Sst的变化,为了区别,记更新后的Cst和Sst分别为Croot和Sroot
先考虑简单的,Croot的值,如果不选x,那么方案数不变,如果选x,那么每一个原来的方案数都可以对应着Cx种方案数,合并一下就是Cst+Cst×Cx=Cst×(Cx+1)
对于Sroot的值,同样考虑是否选择x,如果不选择,那么对Sroot的贡献还是Sst,也就是原来的方案
如果选择了x,情况稍微复杂一点,分别考虑Tst和Tx
对于Tst上的点的贡献
每一个值为Sst的方案都对应着Cx次贡献,所以对Sroot的贡献为 Cx×Sst
对于Tx上的点
同样的,每一个值为Sx一个方案都对应着Cst次贡献,所以对Sroot的贡献为Cst×Sc
所以,Sroot=Sst+Cx×Sst+Cst×Sc=(1+Cx)×Sst+Cst×Sc
#include <bits/stdc++.h> typedef long long LL; using namespace std; const int mod = 1000000007; const int maxn = 112345; LL dp[maxn][2]; vector<int> edge[maxn]; void Link(int st,int ed){ edge[st].push_back(ed); edge[ed].push_back(st); } void init(int n){ for(int i=0;i<n;i++){ edge[i].clear(); } } void dfs(int st,int fa){ dp[st][1] = 1; dp[st][0] = 1; for(auto & x:edge[st]){ if(x != fa){ dfs(x,st); (dp[st][1] *= dp[x][0] + 1) %= mod; (dp[st][1] += dp[st][0] * dp[x][1]) %= mod; (dp[st][0] *= dp[x][0] + 1) %= mod; } } } class SubtreesCounting { public: int sumOfSizes( int n, LL a0, LL b, LL c, LL m ) { init(n); for(int i=1;i<n;i++){ Link(i,a0 % i); a0 = (b * a0 + c) % m; } dfs(0,-1); LL ans = 0; for(int i=0;i<n;i++){ (ans += dp[i][1]) %= mod; } return (int)ans; } };
相关文章推荐
- node.js学习之自己编写命令行工具CLI
- 简单keystore操作(更新中)
- CentOS 搭建Git Gitosis 服务器
- socket C 客户端发送数据到服务端,操作mysql数据库
- 23种设计模式(5):原型模式
- FZU 2087 统计树边
- linux下message没有了
- JAVA设计模式之单例模式
- JSP中的各种中文乱码问题解决方案
- Python学习记录七---继承、多态和封装
- SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-007-定义切面的around advice
- Linux 下实现进程退出后自动重启
- BZOJ 2626: JZPFAR|K-D tree
- VS中CordovaApp 环境详细配置
- 可移动的CollectionViewCell
- div在宽度设为100%时,若设置左边填充,则右边将会溢出的问题
- bootstrap fileinput-上传回调
- js-我理解的闭包
- 【Android】17.4 Activity与IntentService的绑定
- idea python sdk