P4071 [SDOI2016]順列カウント|順列と組み合わせ

タイトルの説明

&1&to&n&配列&a&シーケンスが&m&position&i&を正確に満たす数がわかるので、&a_i = i&になります。

答えはモジュロ&10 ^ 9 + 7&です。

入力フォーマット

この質問シートのテストポイントには複数のデータセットがあります。

入力の最初の行は整数&T&で、テストデータの整数を表します。

次の&T&行。各行は、テストデータのセットを示しています。

テストデータの各セットについて、1行に2つの整数を入力します。これは、&n&および&m&を表します。

出力フォーマット

合計&T&行が出力され、テストデータの各セットについて、答えを表す整数の行が出力されます。


错排公式f[i]=(i-1)(f[i-1]+f[i-2])

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=1e9+7,N=1e6+10,M=1e6;
#define int long long
inline int read(){
	int x=0; char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while('0'<=c&&c<='9'){ x=(x<<1)+(x<<3)+(c^48); c=getchar(); }
	return x;
}
int jc[N],inv[N],D[N];
inline int ksm(int x,int y){
	int res=1;
	while(y){
		if(y&1)res=res*x%mod;
		x=x*x%mod; y>>=1;
	}
	return res;
}
inline void pre(){
	jc[0]=1; for(int i=1;i<=M;i++)jc[i]=jc[i-1]*i%mod;
	inv[M]=ksm(jc[M],mod-2);
	for(int i=M-1;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
	D[0]=1,D[1]=0,D[2]=1;
	for(int i=3;i<=M;i++)D[i]=(i-1)*(D[i-1]+D[i-2])%mod;
}
inline int C(int x,int y){
	if(y>x)return 0;
	return jc[x]*inv[x-y]%mod*inv[y]%mod;
}
int n,m;
signed main(){
	int T=read(); pre();
	while(T--){
		n=read(),m=read();
		printf("%lld\n",C(n,m)*D[n-m]%mod);
	}
}

おすすめ

転載: www.cnblogs.com/naruto-mzx/p/12677782.html