洛谷传送门
BZOJ传送门
题目描述
一开始森林里面有 N N N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友。每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友。经过 N − 1 N-1 N−1次打架之后,整个森林的小猴都会成为好朋友。 现在的问题是,总共有多少种不同的打架过程。 比如当 N = 3 N=3 N=3时,就有 { 1 − 2 , 1 − 3 } { 1 − 2 , 2 − 3 } { 1 − 3 , 1 − 2 } { 1 − 3 , 2 − 3 } { 2 − 3 , 1 − 2 } { 2 − 3 , 1 − 3 } \{1-2,1-3\}\{1-2,2-3\}\{1-3,1-2\}\{1-3,2-3\}\{2-3,1-2\}\{2-3,1-3\} {1−2,1−3}{1−2,2−3}{1−3,1−2}{1−3,2−3}{2−3,1−2}{2−3,1−3}六种不同的打架过程。
输入输出格式
输入格式:
一个整数 N N N。
输出格式:
一行,方案数 m o d    9999991 \mod\ 9999991 mod 9999991。
输入输出样例
输入样例#1:
4
输出样例#1:
96
说明
50%的数据 N ≤ 1 0 3 N\le 10^3 N≤103。 100%的数据 N ≤ 1 0 6 N\le 10^6 N≤106。
解题分析
由 p r u f e r prufer prufer序列可得本质不同的生成树一共有 n n − 2 n^{n-2} nn−2种, 然后再乘上一个阶乘表示选的顺序就好了。
代码如下:
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <cstring>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define ll long long
#define MOD 9999991
ll fpow(ll base, R int tim)
{
ll ret = 1;
W (tim)
{
if (tim & 1) ret = ret * base % MOD;
base = base * base % MOD, tim >>= 1;
}
return ret;
}
int main(void)
{
int n;
scanf("%d", &n); ll ans = fpow(n, n - 2);
for (R int i = 1; i < n; ++i) ans = ans * i % MOD;
printf("%lld", ans);
}