题意:村子里有n个人,给出父亲和儿子的关系,有多少种方式可以把他们排成一列,使得没人会排在他父亲的前面

思路:设f[i]表示以i为根的子树有f[i]种排法,节点i的各个子树的根节点,即它的儿子为c1,c2,c3...ck。

   那么先给节点i的子树确定各自的顺序,为f(c1),f(c2)...f(ck)。

   然后把每棵子树的所有节点看成同一元素,根据有重复元素的全排列方式共有s(i-1)!/(s(c1)!*s(c2)!*...*s(ck)!)

   再根据乘法原理,f[i]=f(c1)* f(c2) *f(c3) * f(c4).....* f(ck) * (s(i) - 1)! / ((s(c1)! * (s(c2))! .... * (s(ck))!)     其中,s[i]表示以i为根的子树的节点个数。

 然后观察这个式子,将每个非根节点带入上式子,可发现每个非根节点u以(s(u) - 1)!的形式出现在分子一次,以s(u)!的形式出现在分母一次。

约分后相当于分子为1,分母为s(u),得到最终的式子是:     f(i) = (s(i)-1)!/(s(1) * s(2) *... *s(k))  (1,2,3...k为以i为根的子树的所有节点,不包括i)

这样,我们可以设立一个虚父节点root=0,把森林连接起来成为一棵树,这样所求的答案即为:     f(root) = (s(root)-1)!/(s(1) * s(2) *... *s(n))

但是最后要让我们求模,而式子中有除法,所以要用到以下定理:     a = (b/c) ==> a%m = b*c^(m-2)%m ( m为素数 )

证明如下:  b = a * c     根据费马小定理 a^(p-1)= 1  %p (p是素数且a不能整除p)     所以 c^(m-1)%m=1%m

               因此 a % m = a*1%m = a * c^(m-1)%m = a*c*c^(m-2)%m = b*c^(m-2)%m;

#include <iostream>
#include <stdio.h>
#include <vector>
/*
组合+除法的求模 题意:
村子里有n个人,给出父亲和儿子的关系,有多少种方式可以把他们排成一列,使得没人会排在他父亲的前面 思路:
设f[i]表示以i为根的子树有f[i]种排法,节点i的各个子树的根节点,即它的儿子为c1,c2,c3...ck。
那么先给节点i的子树确定各自的顺序,为f(c1),f(c2)...f(ck)。
然后把每棵子树的所有节点看成同一元素,根据有重复元素的全排列方式共有s(i-1)!/(s(c1)!*s(c2)!*...*s(ck)!)
再根据乘法原理,f[i]=f(c1)* f(c2) *f(c3) * f(c4).....* f(ck) * (s(i) - 1)! / ((s(c1)! * (s(c2))! .... * (s(ck))!)
其中,s[i]表示以i为根的子树的节点个数。 然后观察这个式子,将每个非根节点带入上式子,可发现每个非根节点u以(s(u) - 1)!的形式出现在分子一次,以s(u)!的形式出现在分母一次。
约分后相当于分子为1,分母为s(u),得到最终的式子是:
f(i) = (s(i)-1)!/(s(1) * s(2) *... *s(k)) (1,2,3...k为以i为根的子树的所有节点,不包括i) 这样,我们可以设立一个虚父节点root=0,把森林连接起来成为一棵树,这样所求的答案即为:
f(root) = (s(root)-1)!/(s(1) * s(2) *... *s(n)) 但是最后要让我们求模,而式子中有除法,所以要用到以下定理:
a = (b/c) ==> a%m = b*c^(m-2)%m ( m为素数 ) 证明如下:
b = a * c
根据费马小定理 a^(p-1)= 1 %p (p是素数且a不能整除p)
所以 c^(m-1)%m=1%m
因此 a % m = a*1%m = a * c^(m-1)%m = a*c*c^(m-2)%m = b*c^(m-2)%m; */
using namespace std;
const long long mod=;
const int maxn=;
vector<int> son[maxn]; //存储儿子节点
int num[maxn]; //存储以i为根的子树的节点个数,包括节点i
int n,m;
long long sum; //求(s(1) * s(2) *... *s(n)) //快速幂,求sum^(mod-2)%mod
long long quickPow(long long a,long long b){
long long ans=;
while(b){
if(b&)
ans=(ans*a)%mod;
a=(a*a)%mod;
b=b>>;
}
return ans;
}
//预处理求阶乘
void init(){
f[]=;
for(int i=;i<maxn;i++){
f[i]=(f[i-]*i)%mod;
}
}
//递归计算子树的节点个数
int dfs(int u){
if(son[u].empty()){
num[u]=;
return num[u];
}
int v;
for(int i=;i<son[u].size();i++){
v=son[u][i];
num[u]+=dfs(v);
}
num[u]++;
return num[u];
}
int main()
{
int t,a,b;
long long ans;
init();
scanf("%d",&t);
while(t--){
for(int i=;i<=n;i++){
num[i]=;
son[i].clear();
}
scanf("%d%d",&n,&m);
for(int i=;i<m;i++){
scanf("%d%d",&a,&b);
son[b].push_back(a);
fa[a]=b;
}
//设立虚父节点0
for(int i=;i<=n;i++){
if(!fa[i]){
son[].push_back(i);
}
}
dfs();
sum=;
for(int i=;i<=n;i++)
sum=(sum*num[i])%mod;
ans=(f[n]*quickPow(sum,mod-))%mod;
printf("%lld\n",ans);
}
return ;
}

UVA 11174 Stand in a Line (组合+除法的求模)的更多相关文章

  1. uva 11174 Stand in a Line

    // uva 11174 Stand in a Line // // 题目大意: // // 村子有n个村民,有多少种方法,使村民排成一条线 // 使得没有人站在他父亲的前面. // // 解题思路: ...

  2. UVA 11174 Stand in a Line 树上计数

    UVA 11174 考虑每个人(t)的所有子女,在全排列中,t可以和他的任意子女交换位置构成新的排列,所以全排列n!/所有人的子女数连乘   即是答案 当然由于有MOD 要求逆. #include & ...

  3. uva 11174 Stand in a Line (排列组合)

    UVa Online Judge 训练指南的题目. 题意是,给出n个人,以及一些关系,要求对这n个人构成一个排列,其中父亲必须排在儿子的前面.问一共有多少种方式. 做法是,对于每一个父节点,将它的儿子 ...

  4. UVA 11174 Stand in a Line 树dp+算

    主题链接:点击打开链接 题意:白书的P103. 加个虚根就能够了...然后就是一个多重集排列. import java.io.PrintWriter; import java.util.ArrayLi ...

  5. 【递推】【推导】【乘法逆元】UVA - 11174 - Stand in a Line

    http://blog.csdn.net/u011915301/article/details/43883039 依旧是<训练指南>上的一道例题.书上讲的比较抽象,下面就把解法具体一下.因 ...

  6. UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)

    这两个题的模型是有n个人,有若干的关系表示谁是谁的父亲,让他们进行排队,且父亲必须排在儿子前面(不一定相邻).求排列数. 我们假设s[i]是i这个节点,他们一家子的总个数(或者换句话说,等于他的子孙数 ...

  7. LeetCode 29 Divide Two Integers (不使用乘法,除法,求模计算两个数的除法)

    题目链接: https://leetcode.com/problems/divide-two-integers/?tab=Description   Problem :不使用乘法,除法,求模计算两个数 ...

  8. 数学:UVAoj 11174 Stand in a Line

    Problem J Stand in a Line Input: Standard Input Output: Standard Output All the people in the bytela ...

  9. 3.29省选模拟赛 除法与取模 dp+组合计数

    LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采 ...

随机推荐

  1. 郑州轻工业OJ1400--这不可能是情书吧

    地址:http://acm.zzuli.edu.cn/problem.php?id=1400 #include<stdio.h> #include<string.h> #inc ...

  2. Change http port in bitnami stack

    My case goes like this. I installed bitnami redmine first with port 80 for http service, but got pro ...

  3. FTP 数字代码的意义

    110 重新启动标记应答. 120 服务在多久时间内ready. 125 数据链路埠开启,准备传送. 150 文件状态正常,开启数据连接端口. 200 命令执行成功. 202 命令执行失败. 211 ...

  4. 一款仿PBA官网首页jQuery焦点图的切换特效

    一款仿PBA官网首页jQuery焦点图的切换特效,非常的简单大方, 在对浏览器兼容性的方面做了不少的功夫.IE6也勉强能过去. 还是一款全屏的焦点图切换特效.大气而清新.很适合简介大方的网站. 下图还 ...

  5. C#主要支持 5 种动态创建对象的方式

    C#主要支持 5 种动态创建对象的方式: 1. Type.InvokeMember 2. ContructorInfo.Invoke 3. Activator.CreateInstance(Type) ...

  6. .Net平台Winform两个ComboBox控件绑定同一个数据源

    今天WINFROM编程遇到这么一个问题:是有关WINFORM中两个comboBox控件绑定同一个数据源的问题,在窗体的界面上有两个comboBox,我在Form1_Load中对他们做了数据绑定(具体代 ...

  7. MongoDB的分组统计 group

    mongodb中的分组聚合用$group,而且处理的最大数据量为100M如果超出需要写入到磁盘,使用格式如下: { $group: { _id: <expression>, <fie ...

  8. php 文件上传简单类---限制仅上传jpg文件

    php 文件上传代码,限制只能上传jpg格式文件,也可以自行添加其它扩展名的文件. <?php /* * 图片上传类 仅限JPG格式图片 * edit by www.jbxue.com at 2 ...

  9. Delphi XE5教程2:程序组织

    内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者 ...

  10. js 数组去重复键

    Array.prototype.deleteEle = function() { var newArr = this; for (var i = newArr.length - 1; i >= ...