[CSAcademy]Connected Tree Subgraphs
题目大意:
给你一棵n个结点的树,求有多少种染色方案,使得染色过程中染过色的结点始终连成一块。
思路:
树形DP。
设f[x]表示先放x时,x的子树中的染色方案数,y为x的子结点。
则f[x]=prod{f[y]}*(size[x]-1)!/prod{size[y]}。
现在我们改变f[x]的含义,让其表示先放x时,整棵子树的方案数。
考虑根的转移对答案做出的贡献。
假设我们从x转移到y,那么就要把y从x中剔除,
设剔除y后的f[x]为t,则t=f[x]*size[y]*(size[x]-1-size[y])!/f[y]/(size[x]-1)!。
这是我们要把x子树中的方案数,也就是t算入f[y]中。
f[y]=f[y]*t*(n-1)!/(size[y]-1)!/(n-1-size[y])!。
把t代入,发现f[y]=f[x]*(n-1-size[y])!*size[y]!/(size[y]-1)!/(n-size[y])!。
时间复杂度O(n)。
#include<cstdio>
#include<cctype>
#include<vector>
typedef long long int64;
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=;
const int mod=1e9+;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
void exgcd(const int &a,const int &b,int &x,int &y) {
if(!b) {
x=;
y=;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
inline int inv(const int &x) {
int ret,tmp;
exgcd(x,mod,ret,tmp);
return (ret%mod+mod)%mod;
}
int f[N],fact[N],size[N];
void dfs(const int &x,const int &par) {
f[x]=size[x]=;
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
size[x]+=size[y];
f[x]=(int64)f[x]*f[y]%mod*inv(fact[size[y]])%mod;
}
f[x]=(int64)f[x]*fact[size[x]-]%mod;
}
void move(const int &x,const int &par) {
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
f[y]=(int64)f[x]*fact[size[]--size[y]]%mod*fact[size[y]]%mod*inv(fact[size[y]-])%mod*inv(fact[size[]-size[y]])%mod;
move(y,x);
}
}
int main() {
const int n=getint();
fact[]=;
for(register int i=;i<n;i++) {
fact[i]=(int64)fact[i-]*i%mod;
}
for(register int i=;i<n;i++) {
add_edge(getint(),getint());
}
int ans=;
dfs(,);
move(,);
for(register int i=;i<=n;i++) {
ans=(ans+f[i])%mod;
}
printf("%d\n",ans);
return ;
}
[CSAcademy]Connected Tree Subgraphs的更多相关文章
- [CSAcademy]Cycle Tree
[CSAcademy]Cycle Tree 题目大意: 定义环树是一张无向连通的简单图,它的生成方式如下: \(2\)个点\(1\)条边的图是环树: 对任意一个环树,加入\(k\)个点\(a_{1\s ...
- [Swift]LeetCode834. 树中距离之和 | Sum of Distances in Tree
An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge co ...
- Google Code Jam 2014 Round 1 A:Problem B. Full Binary Tree
Problem A tree is a connected graph with no cycles. A rooted tree is a tree in which one special ver ...
- [LeetCode] 834. Sum of Distances in Tree 树中距离之和
An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge co ...
- 834. Sum of Distances in Tree —— weekly contest 84
Sum of Distances in Tree An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges a ...
- 【leetcode】834. Sum of Distances in Tree(图算法)
There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges. You are ...
- Codeforces Gym 100650B Countdown DFS
Problem B: CountdownTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/conte ...
- 《算法4》1.5 - Union-Find 算法解决动态连通性问题,Python实现
Union-Find 算法(中文称并查集算法)是解决动态连通性(Dynamic Conectivity)问题的一种算法,作者以此为实例,讲述了如何分析和改进算法,本节涉及三个算法实现,分别是Quick ...
- [CSAcademy]Find the Tree
[CSAcademy]Find the Tree 题目大意: 交互题. 有一棵\(n(n\le2000)\)个结点的树,但是你并不知道树的形态.你可以调用\({\rm query}(x,y,z)\)( ...
随机推荐
- Pycharm 创建 Django admin 用户名和密码
1. 问题 使用PyCharm 创建完Django 项目 想登录admin 页面 却不知道用户名和密码. 用的默认sqlit 2.解决办法 2.1 打开manage.py 控制界面 ...
- java获取mysql数据库表、字段、字段类型、字段注释
最近想要写一个根据数据库表结构生成实体.mapper接口.mapping映射文件.service类的简单代码生成工具,所以查阅了一些资料,怎样获取数据库的表.表中字段.字段类型.字段注释等信息. 最后 ...
- jzoj2700 【GDKOI2012模拟02.01】数字
传送门:https://jzoj.net/senior/#main/show/2700 [题目大意] 令n为正整数,S(n)为n的各位数字之和,令
- HDU2481 Toy
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission ...
- mysql五:数据操作
一 介绍 MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的 ...
- PHP性能追踪及分析工具xhprof的安装与使用
对于本地开发环境来说,进行性能分析xdebug是够用了,但如果是线上环境的话,xdebug消耗较大,配置也不够灵活,因此线上环境建议使用xhprof进行PHP性能追踪及分析. 我们今天就简单介绍一下x ...
- POJ3466(01背包变形)
Proud Merchants Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) ...
- 【转】针对Android上的ROP攻击剖析
引言 ROP(Return-oriented programming),即“返回导向编程技术”.其核心思想是在整个进程空间内现存的函数中寻找适合指令片断(gadget),并通过精心设计返回 ...
- 【bzoj3289】mato的文件管理
首先允许离线,一眼莫队…… 然后考虑对于每次移动,这不就是让你求逆序对嘛(QAQ) 考虑怎么移动? 每次在最后添加一个数,比这个数大的数都会与其形成一个逆序对 每次在最后移除一个数,比这个数大的数都会 ...
- Mac-装机
不过大家可别被「命令行」三个字吓到,其实你只需按步骤来,复制粘贴命令即可快速完成,事实上是很简单的. 一.准备工作: 准备一个 8GB 或以上容量的 U 盘,确保里面的数据已经妥善备份好(该过程会抹掉 ...