列表

详情


NC238725. 至至子的公司排队

描述

至至子开有 n 家公司,第 i 家公司有 c_i 个员工,并且在该公司内形成了 c_i - 1直接上下级的关系(注意到 BOSS 是没有直接上级的)。今天他良心发现想让这 n 家公司的所有员工排队买票旅游。

然而这些人的等级观念很重——他们约定一个人在排队的时候不能排在其直接或间接上级的前面(若 ab 的直接上级或间接上级,bc 的直接/间接上级,则 ac 的间接上级)。

于是至至子很好奇,一共有多少种符合条件的排队方案呢?由于这个数可能很大,所以请输出答案对 取模的结果。

输入描述

第一行一个正整数 n,表示公司的数量,保证 

接下来的 n 行每行描述一个公司,第一个正整数 c_i 表示第 i 个公司的人数。为了方便,我们将 同一公司 内的员工编号为 ,其中 1 为这个公司的 BOSS,没有直接上级。接下来的 c_i - 1 个正整数,分别描述 号员工的直接上级 f_i。保证 ,并且

输出描述

一行一个整数,表示答案对  取模的结果。

示例1

输入:

1
5 1 1 2 3

输出:

6

说明:

23 的直接上司是 14 的直接上级是 25 的直接上级是 3145 的间接上级。

6 种合法的排队方案分别为 (1,2,4,3,5)(1,3,5,2,4)(1,2,3,4,5)(1,3,2,4,5)(1,2,3,5,4)(1,3,2,5,4)。可以发现没有别的合法的排队方案。

示例2

输入:

5
1
1
1
1
1

输出:

120

说明:

5 家公司都只有各自的 BOSS,只考虑其排列方案即可,不难发现为 5! = 120 种。

示例3

输入:

3
2 1
4 1 2 3
4 1 2 2

输出:

6300

示例4

输入:

14
2 1
4 4 4 1
3 3 1
3 1 2
6 1 4 6 4 2
7 5 7 7 6 1 6
4 1 2 1
2 1
8 4 4 1 2 2 6 6
8 6 6 7 4 5 1 1
5 4 4 5 1
7 3 6 3 1 5 2
8 3 6 1 7 5 4 5
8 6 6 7 8 7 8 1

输出:

430390195

说明:

记得输出答案对 10^9 + 7 取模的结果。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Go 解法, 执行用时: 748ms, 内存消耗: 10344K, 提交时间: 2022-12-17 11:37:38

package main

import "fmt"

const (
	M = int(1e5)
	mod = int(1e9) + 7
)

var g [M + 5][]int
var f [M + 5]int
var sz [M + 5]int
var fac [M + 5]int

func get_fac() {
	fac[0] = 1
	for i := 1; i <= M; i++ {
		fac[i] = fac[i - 1] * i % mod
	}
}

func quick(a int, b int) int {
	s := 1
	for b > 0 {
		if (b & 1) == 1 {
			s = s * a % mod
		}
		a = a * a % mod
		b >>= 1
	}
	return s % mod
}

func inv(n int) int {
	return quick(n, mod - 2)
}

func dfs(u int) {
	f[u], sz[u] = 1, 1
	for _, v := range g[u] {
		dfs(v)
		sz[u] += sz[v]
		f[u] = f[u] * f[v] % mod * inv(fac[sz[v]]) % mod
	}
	f[u] = f[u] * fac[sz[u] - 1] % mod
}

func main() {
	get_fac()
	var n int
	fmt.Scan(&n)
	sc := 1
	var c, fa int
	g[1] = make([]int, 0)
	for i := 1; i <= n; i++ {
		fmt.Scan(&c)
		g[1] = append(g[1], sc + 1)
		for j := 2; j <= c; j++ {
			fmt.Scan(&fa)
			g[sc + fa] = append(g[sc + fa], sc + j)
		}
		sc += c
	}
	dfs(1)
	fmt.Println(f[1])
}

C++(g++ 7.5.0) 解法, 执行用时: 43ms, 内存消耗: 3308K, 提交时间: 2022-08-20 15:56:32

#include<bits/stdc++.h>
using namespace std;using ll=long long;
#define endl '\n'
#define rep(i,l,r)for(ll(i)=(l);(i)<=(r);++(i))
const int MOD=1e9+7,N=1e5+10;ll f[N];int js;int qsm(int a,int b){ll res=1;while(b){if(b&1)res=res*a%MOD;a=(ll)a*a%MOD;b>>=1;}return res;}ll res=1;void Solve(){int n;cin>>n;vector<vector<int>>son(n+1);rep(i,2,n){int x;cin>>x;son[x].push_back(i);}vector<int>num(n+1);vector<ll>dp(n+1,1);function<void(int)>dfs=[&](int now){for(auto x:son[now]){dfs(x);num[now]+=num[x];dp[now]=dp[now]*dp[x]%MOD*qsm(f[num[x]],MOD-2)%MOD;}dp[now]=dp[now]*f[num[now]]%MOD;num[now]+=1;};dfs(1);res=res*dp[1]%MOD*qsm(f[num[1]],MOD-2)%MOD;rep(i,1,n)res=res*(++js)%MOD;return;}int main(){std::ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);f[0]=1;rep(i,1,1e5)f[i]=f[i-1]*i%MOD;int t;cin>>t;while(t--)Solve();cout<<res;return 0;}

C++(clang++ 11.0.1) 解法, 执行用时: 52ms, 内存消耗: 3812K, 提交时间: 2023-02-03 17:20:34

#include<bits/stdc++.h>
using namespace std;
const int p=1e9+7;
const int N=1e5+5;
using ll=long long;

ll son[N],ans=1,sum;
vector<int>V[N];

ll qpow(ll a,ll b)
{
	ll res=1;
	while(b)
	{
		if(b&1)res=res*a%p;
		a=a*a%p;
		b>>=1;
	}
	return res;
}

void dfs(int x)
{
	son[x]++;
	for(auto u:V[x])
	{
		dfs(u);
		son[x]+=son[u];
	}
	ans=ans*qpow(son[x],p-2)%p;
}

int n;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int c;cin>>c;
		for(int i=1;i<=c;i++)
		{
			sum++;
			ans=ans*sum%p;
		}
		for(int i=1;i<=c;i++)
		{
			son[i]=0;
			V[i].clear();
		}
		for(int i=1;i<=c-1;i++)
		{
			int x;cin>>x;
			V[x].push_back(i+1);
		}
		dfs(1);	
	}
	cout<<ans;
	return 0;
}

上一题