【CodeForces - 289D】Polo the Penguin and Houses (带标号的无根树,Cayley定理,Prufer编码)

题干:

Little penguin Polo loves his home village. The village has n houses, indexed by integers from 1 to n. Each house has a plaque containing an integer, the i-th house has a plaque containing integer pi (1 ≤ pi ≤ n).

Little penguin Polo loves walking around this village. The walk looks like that. First he stands by a house number x. Then he goes to the house whose number is written on the plaque of house x (that is, to house px), then he goes to the house whose number is written on the plaque of house px (that is, to house ppx), and so on.

We know that:

  1. When the penguin starts walking from any house indexed from 1 to k, inclusive, he can walk to house number 1.
  2. When the penguin starts walking from any house indexed from k + 1 to n, inclusive, he definitely cannot walk to house number 1.
  3. When the penguin starts walking from house number 1, he can get back to house number 1 after some non-zero number of walks from a house to a house.

You need to find the number of ways you may write the numbers on the houses' plaques so as to fulfill the three above described conditions. Print the remainder after dividing this number by 1000000007 (109 + 7).

Input

The single line contains two space-separated integers n and k (1 ≤ n ≤ 1000, 1 ≤ k ≤ min(8, n)) — the number of the houses and the number k from the statement.

Output

In a single line print a single integer — the answer to the problem modulo 1000000007 (109 + 7).

Examples

Input

5 2

Output

54

Input

7 4

Output

1728

题目大意:

给定 n 和k,n 表示有n个房子,然后每个有一个编号,一只鹅要从一个房间中开始走,下一站就是房间的编号,现在要你求出有多少种方法编号并满足下面的要求:
1.如果从1到k开始走,一定能走到 1。

2.如果从k+1到n 开始走,一定走不到 1.

3.如果从 1 开始走,那么一定能回到1,并且走过房间数不为0.

解题报告:

  做这个题涉及到一个结论,,(当然不知道这个结论,这题中也可以通过规律看出来)。

  有一种序列叫,Purfer序列,有一个定理叫Cayley定理。

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

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

感谢wjh大佬的讲解orz(链接)

所以对于k前面一部分就是k^(k-1)了,,后面一部分很好推出来是(n-k)^(n-k)。求和就行了。

(因为通过题意很容易得出结论,,1~k 和 k+1~n  这俩区间不能有交集的,,也就是 互相不可达的。所以分开求就好了)

其实前半部分能想成是一棵树的结构就不容易啊2333.、、

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll mod = 1e9 + 7;
ll f[MAX],n,k;
ll qpow(ll a,ll k) {
	ll res = 1;
	while(k) {
		if(k&1) {
			res = (res*a)%mod;
		}
		k>>=1;
		a = (a*a)%mod;
	}
	return res%mod;
}
int main()
{
	f[1]=0;f[2]=1;
	for(int i = 3; i<=1005; i++) {
		f[i] = (i-1) * ((f[i-1]+f[i-2])%mod)%mod;
//		printf("%lld\n",f[i]);
	}
	cin>>n>>k;
	printf("%lld\n",(qpow(k,k-1)*qpow(n-k,n-k))%mod);
	return 0 ;
 }

 

你可能感兴趣的:(知识点,Codeforce~,思维)