对于一组数据
n,m
。
ans=Cmn∗dp[n−m]
dp[i]
表示
i
的错排数。
那就是考虑如何求
求
dpn
:
1.将第
n
个数放入前
2.
那么得到递推式
dp1=0
,
dp2=1
(i>2)时:dpi=(i−1)∗(dpi−1+dpi−2)
【代码】
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#define N 1000005
#define M 160405
#define Mod 1000000007
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
typedef pair<int,ll> pa;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,m,ans,T;
ll fac[N],Inv[N],d[N];
ll Qpow(ll x,int y)
{
ll rtn=1;
while(y) {
if(y&1) rtn=1LL*x*rtn%Mod;
x=1LL*x*x%Mod;y>>=1;
}
return rtn;
}
int main()
{
fac[0]=Inv[0]=1;d[2]=d[0]=1;
for(register int i=1;i<N;i++)
{
fac[i]=1LL*i*fac[i-1]%Mod;
Inv[i]=(i>1)?(Mod-Mod/i)*Inv[Mod%i]%Mod:1;
d[i]=(i>2)?1LL*(i-1)*(d[i-1]+d[i-2])%Mod:d[i];
}
for(register int i=1;i<N;i++) Inv[i]=Inv[i]*Inv[i-1]%Mod;
T=read();
while(T--)
{
n=read(),m=read();
ans=fac[n]*Inv[m]%Mod*Inv[n-m]%Mod*d[n-m]%Mod;
printf("%d\n",ans);
}
return 0;
}