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.
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.
For each test case, output the answer mod 1000000007(10^9 + 7).
2 1 1 3 1Sample Output
1 4
题意:t 组数据,输入一个 n,k, n个人分配东西,问至少k个人分配到属于自己的编号的方案数。
思路:组合数 + 错排,中间要用到求逆元;n个数字里要求至少k个数字位置不变,其余进行错排的方案数,容易想到不变的数字从k枚举到n,每次取i(k <= i < n)个出来,对剩下的n-i个进行错排;
注意输入 n k,为 long long 时,一定要用 Visual C++
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mod 1000000007
#define ll long long
#define Max 10010
ll a[Max+10],fic[Max+10];
void fff()
{
//int i;
a[0] = 1;
a[1] = 0;
a[2] = 1;
fic[1] = 1;
fic[2] = 2;
for(ll i = 3;i<Max;i++)
{
a[i] = ((i-1)*a[i-1]%mod + (i-1)*a[i-2]%mod)%mod;
fic[i] = (fic[i-1] * i)%mod;
}
}
ll p_pow(ll a,ll b)
{
ll res = 1;
while(b)
{
if(b&1) res = res*a%mod;
b>>=1;
a = a*a%mod;
}
return res;
}
ll C(ll n,ll m)
{
if(m>n) return 0;
if(m==0) return 1;
if(m>n-m)
m = n-m;
ll sum = 1;
ll sum1 = 1;
ll k = n;
for(ll i = 1;i<=m;i++)
{
sum = sum*k%mod;
k--;
sum1 = sum1 * i %mod; // 因为 mod 是个素数 所以分母可以先取余,再求逆元;
}
return sum*p_pow(sum1,mod-2)%mod;
}
int main()
{
ll n,m;
fff();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
ll res = 0;
for(ll i = 0;i<m;i++)
{
res = (res + C(n,i)*a[n-i]%mod) %mod;
}
printf("%lld\n",(fic[n] - res + mod)%mod );
}
return 0;
}