【nyoj-127】星际之门(一)(Cayley公式 / Prufer序列)

版权声明:如果有什么问题,欢迎大家指出,希望能和大家一起讨论、共同进步。 https://blog.csdn.net/QQ_774682/article/details/84451698

星际之门(一)

时间限制:3000 ms  |  内存限制:65535 KB

难度:3

描述

公元3000年,子虚帝国统领着N个星系,原先它们是靠近光束飞船来进行旅行的,近来,X博士发明了星际之门,它利用虫洞技术,一条虫洞可以连通任意的两个星系,使人们不必再待待便可立刻到达目的地。

帝国皇帝认为这种发明很给力,决定用星际之门把自己统治的各个星系连结在一起。

可以证明,修建N-1条虫洞就可以把这N个星系连结起来。

现在,问题来了,皇帝想知道有多少种修建方案可以把这N个星系用N-1条虫洞连结起来?

输入

第一行输入一个整数T,表示测试数据的组数(T<=100)
每组测试数据只有一行,该行只有一个整数N,表示有N个星系。(2<=N<=1000000)

输出

对于每组测试数据输出一个整数,表示满足题意的修建的方案的个数。输出结果可能很大,请输出修建方案数对10003取余之后的结果。

样例输入

2
3
4

样例输出

3
16

思路:

题意很简单,就是如果有n个点,能生成多少种不同的树,这道题目实际就是考察Purfer序列应用(Purfer序列的博客),一颗n个结点的树,转成一个Purfer序列后,序列的元素有n-2个,而一棵树和一种序列是一一对应的(一棵n个节点的无根树唯一地对应了一个长度为n-2的数列),因此要问能产生多少树,只要看序列的种类数,序列有n-2个位置,每个位置上 的元素有n种(序列中是允许有重复元素的),因此序列的种类即不同的树的种类有n^{n-2}种。如果明白这一步后,那么剩下的就是单纯考察一个快速幂取模了。

Cayley定理:有n个节点的完全图的生成树的数量是n^{n-2},或者说n个节点的带标号的无根树有n^{n-2}个。

Prufer编码:给定一棵带标号的无根树,找出编号最小的叶子节点,写下与它相邻的节点的编号,然后删掉这个叶子节点。反复执行这个操作直到只剩两个节点为止。

一个有趣的推广是,n个节点的度依次为D1, D2, …, Dn的无根树共有(n-2)! / [ (D1-1)!(D2-1)!..(Dn-1)! ]个,因为此时Prüfer编码中的数字i恰好出现Di-1次。(转自此博客

ac代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#include<set>
#include<iostream>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#define ll long long
#define mod 10003
#define eps 1e-8
using namespace std;
ll qsm(ll a,ll b)
{
	ll t=1;
	while(b)
	{
		if(b&1)
		{
			t=(t*a)%mod;
		}
		a=(a*a)%mod;
		b>>=1;
	}
	return t%mod;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		printf("%lld\n",qsm(n,n-2));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/QQ_774682/article/details/84451698