n个里选m个 然后n-m个里错排
***
错排相关公式
Dn=(n-1)*(Dn-1+Dn-2) D1=0,D2=1
Dn=n*Dn-1+(-1)^(n-2)=n*Dn-1+(-1)^n
Dn=n!(1-1/1!+1/2!-1/3!+……±1/n!)
#include<cstdio> #include<cstdlib> #include<algorithm> #define P 1000000007 using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read (ll &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') c=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=1000000; ll D[N+5]; ll fac[N+5],inv[N+5]; inline void Pre() { D[0]=1; D[1]=0; D[2]=1; for (int i=3;i<=N;i++) D[i]=(D[i-1]+D[i-2])%P*(i-1)%P; fac[0]=1; for (int i=1;i<=N;i++) (fac[i]=fac[i-1]*i)%=P; inv[1]=1; for (int i=2;i<=N;i++) (inv[i]=(P-P/i)*inv[P%i])%=P; inv[0]=1; for (int i=1;i<=N;i++) (inv[i]*=inv[i-1])%=P; } inline ll C(ll n,ll m){ return fac[n]*inv[m]%P*inv[n-m]%P; } int main() { freopen("t.in","r",stdin); freopen("t.out","w",stdout); ll Q,n,m,ans; Pre(); read(Q); while (Q--) { read(n); read(m); if (n<m) printf("0\n"); ans=C(n,m)*D[n-m]%P; printf("%lld\n",ans); } return 0; }