P4071 [SDOI2016]排列计数

towboa / 2023-05-06 / 原文

 

错位排列板子题,plus: 组合数取模

const int N=1e6;
#define int long long
 const int mod =1e9+7 ;
int n,m,D[N+3] ;

#define ll long long
ll inv[N+3];
int F[N+3] ;
 
int fpow(int n, int p, int mod){
	n %= mod;
	int ans = 1, base = n;
	while(p){
		if(p & 1) ans = ans * base % mod;
		base = base * base % mod;
		p >>= 1;
	}
	return ans;
}
void get_inv(ll n,ll p){
    inv[N] = fpow(F[N], mod - 2, mod);
	for(int i = N - 1; i >= 0; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
}
 
ll C(ll n,ll m){
    return F[n]*inv[m]%mod*inv[n-m]%mod;
}
  
 void sov(){
 	cout << (C(n,m)*D[n-m])%mod <<endl;
 }
 signed main() {
 	F[0]=1;
 	for(int i=1;i<=1e6;i++) F[i]=F[i-1]*i,F[i]%=mod;
 	get_inv(1e6,mod);
 	
 	D[0]=0,D[1]=0,D[2]=1;
 	for(int i=3;i<=1e6;i++) 
 		D[i] =(i-1)*(D[i-1]+D[i-2]),D[i]%=mod;
 	
 	int tes;
 	cin>>tes;
 	while(tes--){
 		cin>>n>>m;
 		if(n==m) cout<<1<<endl; else sov() ;
 	}
 }