小猴打架(Prufer 序列)
题目描述
一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友。每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友。经过N-1次打架之后,整个森林的小猴都会成为好朋友。
现在的问题是,总共有多少种不同的打架过程。
比如当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}六种不同的打架过程。
现在的问题是,总共有多少种不同的打架过程。
比如当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}六种不同的打架过程。
输入
一个整数N。
输出
一行,方案数mod 9999991。
样例输入 Copy
4
样例输出 Copy
96
提示
50%的数据N<=10^3。
100%的数据N<=10^6。
100%的数据N<=10^6。
思路:其实就是求n阶完全图的生成树,在乘上一个(n-1)!。
了解一下:
Prufer 序列
#pragma GCC optimize(3 , "Ofast" , "inline")
#include <bits/stdc++.h>
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int , int> pi;
template<class T>
inline void read (T &x) {
x = 0;
int sign = 1;
char c = getchar ();
while (c < '0' || c > '9') {
if ( c == '-' ) sign = - 1;
c = getchar ();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar ();
}
x = x * sign;
}
const int maxn = 3e5 + 10;
const int inf = int (1e9);
const ll INF = ll (1e18);
const double PI = acos (- 1);
const int mod = 9999991;
const double eps = 1e-8;
ll qpow(ll a,ll b) {
ll ans = 1;
while (b) {
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main () {
ll n;
read (n);
ll ans = qpow (n,n-2)%mod;
rep (i,1,n-1) ans=ans*i%mod;
printf ("%lld\n",ans);
return 0;
}