从 $n$ 个数中选 $m$ 个不错排,那就是说 $n-m$ 个数是错排的.
用组合数乘一下就好了.
Code:
#include <cstdio>
#include <algorithm>
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
namespace IO
{
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
};
typedef long long ll;
const int mod=1000000007,N=1000002;
ll rev[N],f[N],fac[N],inv[N];
ll qpow(ll base,ll k)
{
ll tmp=1;
for(;k;base=base*base%mod,k>>=1) if(k&1) tmp=tmp*base%mod;
return tmp;
}
ll C(int n,int m) { return fac[n]*inv[m]%mod*inv[n-m]%mod; }
int main()
{
using namespace IO;
// setIO("input");
int T=rd(),n,m,i,j;
f[1]=0,f[0]=f[2]=1;
fac[0]=inv[1]=inv[0]=1;
for(i=3;i<N;++i) f[i]=(ll)(i-1)*(f[i-1]+f[i-2])%mod;
for(i=1;i<N;++i) fac[i]=fac[i-1]*i%mod,inv[i]=qpow(fac[i],mod-2);
for(int cas=1;cas<=T;++cas)
{
n=rd(),m=rd();
printf("%lld\n",m>n?0:C(n,m)*f[n-m]%mod);
}
return 0;
}