NC20584. [SDOI2016]排列计数
描述
输入描述
第一行一个数 T,表示有 T 组数据。
接下来 T 行,每行两个整数 n、m。
T=500000,n ≤ 1000000,m ≤ 1000000
输出描述
输出 T 行,每行一个数,表示求出的序列数
示例1
输入:
5 1 0 1 1 5 2 100 50 10000 5000
输出:
0 1 20 578028887 60695423
C++11(clang++ 3.9) 解法, 执行用时: 367ms, 内存消耗: 36480K, 提交时间: 2020-10-09 21:44:37
#include<iostream> #include<cstdio> using namespace std; const int M=1000000; const int MOD=1e9+7; long long t,n,m,d[M+1],jc[M+1],inv[M+1],invjc[M+1]; void pre(){ d[0]=invjc[0]=invjc[1]=inv[1]=d[2]=jc[0]=jc[1]=1; for(register int i=2;i<=M;i++){ inv[i]=((MOD-MOD/i)*inv[MOD%i])%MOD; jc[i]=(i*jc[i-1])%MOD; invjc[i]=(invjc[i-1]*inv[i])%MOD; } for(register int i=3;i<=M;i++){ d[i]=(i-1)*(d[i-1]+d[i-2])%MOD; } } int main() { pre(); scanf("%lld",&t); while(t--){ scanf("%lld%lld",&n,&m); printf("%lld\n",(((jc[n]*invjc[m]%MOD)*invjc[n-m]%MOD)*d[n-m]%MOD)); } return 0; }