前言
这不是错排吗?!
诶,我怎么一眼就看出来了?
诶,我怎么打不来错排?
诶,我怎么躺地上了?
题目
正题
(m) 个数字是对应的位置那么就有 (C_n^m) 种情况,剩下的数字只需要求出错排数,即求出 (D(n-m)),就搞定了
那么怎么求错排呢?前往博客食用:
组合数就不用多说了吧,配合逆元求解
答案就是 (C_n^m * D(n-m))
下面是丑陋的代码:
//12252024832524
#include <cstdio>
#include <algorithm>
#define Min(x,y) (x<y?x:y)
#define Max(x,y) (x>y?x:y)
using namespace std;
typedef long long LL;
const int MAXN = 1000005;
const int MOD = 1e9 + 7;
int n,m;
LL cp[MAXN],inv[MAXN],jc[MAXN];//cp即错排,jc即阶乘
int Read()
{
int x = 0,f = 1;char c = getchar();
while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
return x * f;
}
void Put(LL x)
{
if(x > 9)
Put(x/10);
putchar(x%10^48);
}
void pre()
{
cp[1] = 0;
cp[2] = 1;
jc[1] = 1;
inv[0] = inv[1] = 1;
for(int i = 3;i < MAXN;++ i)
cp[i] = (i-1) * (cp[i-1] + cp[i-2]) % MOD;
for(int i = 2;i < MAXN;++ i)
{
jc[i] = jc[i-1] * i % MOD;
inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
}
for(int i = 1;i < MAXN;++ i)
inv[i] = inv[i-1] * inv[i] % MOD;
return;
}
LL C(int x,int y)
{
return jc[x] * inv[y] % MOD * inv[x-y] % MOD;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
pre();
for(int T = Read(); T ;-- T)
{
n = Read();
m = Read();
if(n == m)
putchar('1');
else
Put(C(n,m) * cp[n-m] % MOD);
putchar('
');
}
return 0;
}