UPC-小猴打架

学习犹如逆水行舟,不进则退

小猴打架

题目描述

一开始森林里面有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。

输出

一行,方案数mod 9999991。

Sample Input

4

Sample Output

96

Hint

50%的数据N<=103
100%的数据N<=106

题目思路
这题需要一个知识点就是Purfer数列
形象的栗子就是,以一个点为跟,剩下的n-1个集以何种方法与这个根相连。
一共是nn-2种情况。
然后既然确定了这个根了,那么剩下的n-1个有(n-1)!种排列方法
故,答案为(n-1)!*nn-2
通过普通的模拟运算就可以做出来了
AC代码如下

#include<algorithm>
#include<iostream>
#include<string.h>
#include<utility>
#include<stdio.h>
#include<vector>
#include <stack>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<map>
#pragma warning(disable:4244)
#define PI 3.1415926536
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const char char_inf = 127;
inline ll read() {
	ll c = getchar(), Nig = 1, x = 0;
	while (!isdigit(c) && c != '-')c = getchar();
	if (c == '-')Nig = -1, c = getchar();
	while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
	return Nig * x;
}
inline void out(ll a)
{
	if (a < 0)putchar('-'), a = -a;
	if (a >= 10)out(a / 10);
	putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
	ll res = 1;
	while (n > 0) {
		if (n & 1)res = (res * x) % mod;
		x = (x * x) % mod; n >>= 1;
	}
	return res;
}
#define read read()
ll ans = 0;
int main()
{
	ll n = read;
	ans = qpow(n, n - 2, 9999991);
	for (int i = 1; i < n; i++)
	{
		ans *= i;
		ans %= 9999991;
	}
	cout << ans << endl;
	return 0;
}
书山有路勤为径,学海无涯苦作舟。
发布了32 篇原创文章 · 获赞 11 · 访问量 1184

猜你喜欢

转载自blog.csdn.net/qq_35339563/article/details/104783279