JZOJ.5273【NOIP2017模拟8.14】亲戚

Description
 
Input
Output
 
Sample Input
4
0 1 1 0
Sample Output
8
 
Data Constraint

.对于一棵子树,位于同一个深度的点个数用组合公式,整棵子树节点用排列公式,再随便整理一下就好了......

$\dfrac {n!} {\prod _{i=1}^{n}S\left( i\right) }$ 其中 $S\left( i\right)$表示以i为根节点的子树的点的个数

除法的逆元一下就行了。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #define N 200005
 7 #define mo 1000000007
 8 using namespace std;
 9 int n,s[N],chu[N],next[N*2],head[N],to[N*2],num;
10 long long ans;
11 void add(int u,int v){
12     num++;
13     next[num]=head[u];
14     to[num]=v;
15     head[u]=num;
16 }
17 void dfs(int x){
18     if (chu[x]==0) {
19         s[x]=1;
20         return;
21     }
22     for (int i=head[x];i;i=next[i]){
23         dfs(to[i]);
24         s[x]+=s[to[i]];
25     }
26     s[x]++;
27 } 
28 void kuai(int x,int b){
29     long long a=1,qwq=b,qaq=x;
30     while (qwq){
31         if (qwq&1) a=(qaq*a)%mo;
32         qwq>>=1;
33         qaq=(qaq*qaq)%mo;
34     }
35     ans=(ans*a)%mo;
36 }
37 int main(){
38     scanf("%d",&n);
39     num=0;
40     for (int i=1,u=0;i<=n;i++){
41         scanf("%d",&u);
42         add(u,i);
43         chu[u]++;
44     }
45     dfs(0);
46     ans=1;
47     for (int i=1;i<=n;i++)
48         ans=(i%mo*ans)%mo;
49     for (int i=1;i<=n;i++)
50         if (s[i]!=1) 
51         kuai(s[i],mo-2);
52     printf("%lld",ans);
53     return 0;
54 }
神奇的代码

这里还有一道不错的类似题目,在这题基础上多了可违反规矩的次数。

转载于:https://www.cnblogs.com/Lanly/p/7359669.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值