Accept: 30 Submit: 94
Time Limit: 1000 mSec Memory Limit : 262144 KB
Problem Description
N wizards are attending a meeting. Everyone has his own magic wand. N magic wands was put in a line, numbered from 1 to n(Wand_i owned by wizard_i). After the meeting, n wizards will take a wand one by one in the order of 1 to n. A boring wizard decided to reorder the wands. He is wondering how many ways to reorder the wands so that at least k wizards can get his own wand.
For example, n=3. Initially, the wands are w1 w2 w3. After reordering, the wands become w2 w1 w3. So, wizard 1 will take w2, wizard 2 will take w1, wizard 3 will take w3, only wizard 3 get his own wand.
Input
First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.
For each test case: Two number n and k.
1<=n <=10000.1<=k<=100. k<=n.
Output
For each test case, output the answer mod 1000000007(10^9 + 7).
Sample Input
Sample Output
递归关系式为:D(n)=(n-1)(D(n-1)+D(n-2))
D(1)=0,D(2)=1
可以得到:
错排公式为 f(n) = n![1-1/1!+1/2!-1/3!+……+(-1)^n*1/n!]
其中,n!=1*2*3*.....*n,
特别地,有0!=0,1!=1.
第一步,“错排” 1 号元素(将 1 号元素排在第 2 至第 n 个位置之一),有 n - 1 种方法。
第二步,“错排”其余 n - 1 个元素,按如下顺序进行。视第一步的结果,若1号元素落在第 k 个位置,第二步就先把 k 号元素“错排”好, k 号元素的不同排法将导致两类不同的情况发生:
1、 k 号元素排在第1个位置,留下的 n - 2 个元素在与它们的编号集相等的位置集上“错排”,有 f(n -2) 种方法;
2、 k 号元素不排第 1 个位置,这时可将第 1 个位置“看成”第 k 个位置(也就是说本来准备放到k位置为元素,可以放到1位置中),于是形成(包括 k 号元素在内的) n - 1 个元素的“错排”,有 f(n - 1) 种方法。据加法原理,完成第二步共有 f(n - 2)+f(n - 1) 种方法。
根据乘法原理, n 个不同元素的错排种数
f(n) = (n-1)[f(n-2)+f(n-1)] (n>2) 。
LL exgcd(LL a, LL b,LL &x,LL &y)//这里是引用,新的x,y,是由以前的x,y,的值得到
{
if (b == 0)
{ x = 1; y = 0; return a; }//x,y,的初始化
LL g = exgcd(b, a % b ,x ,y);
LL t = x - a / b * y;//回溯求逆元
x = y;
y = t;
return g;//g表示a和b的最大公约数
}
LL fac[N]; //
void init()
{
LL i;
fac[0]=1;
for (LL i = 1; i < N; i++)
fac[i] = fac[i - 1] * i % MOD;
}
LL exgcd(LL a, LL b, LL &x, LL &y) {
if (!b) {x = 1; y = 0; return a;}
LL d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
LL inv(LL a, LL n) {
LL x, y;
exgcd(a, n, x, y);
return (x + n) % n;
}
LL C(LL n, LL m) {
return fac[n] * inv(fac[m] * fac[n - m] % MOD, MOD) % MOD;
}
AC代码就不再贴了。