组合数的求解

将n的阶乘和x ^ mod - 2(1 <= x <= 2000000)都初始化出来,大约可以减少一半以上的时间(具体不太清楚,应该会随着n的变化而变化)

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 2e6 + 5; 
const LL mod = 1e9 + 7;

LL num[N];
LL ans[N];
//快速幂
LL qpow(LL a, LL b) {
	LL res = 1;
	
	while (b) {
		if(b & 1) res = res * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	
	return res;
} 

void init() {
	num[1] = 1;
	for (int i = 2; i <= 2000000; i ++ ) {
		num[i] = (num[i - 1] * i) % mod;
	}
	
	ans[2000000] = qpow(num[2000000], mod - 2) % mod;
	
	for (int i = 2000000; i >= 1; i -- ) {
		ans[i - 1] = ans[i] * i % mod; 
	}
}

LL solve(LL m, LL n) {
	return num[n] * ans[m] % mod * ans[n - m] % mod;
}

int main() {
	int t;
	cin >> t;
		
	//将n的阶乘和x ^ mod - 2(1 <= x <= 2000000)都初始化出来,大约可以减少一半以上的时间 
	init(); 
		
	while (t -- ) {
		int n;		
		scanf("%d", &n);
		
		if(n == 1) {
			cout << "1 1" << endl;
			continue;
		}
		
		printf("%lld %lld\n", solve(n - 1, 2 * n), (solve(n, 2 * n) - solve(n - 1, 2 * n) + mod) % mod);  
	}	
	
	
	
	
	return 0;
}
posted on 2022-11-08 18:34  知白-剑仙  阅读(34)  评论(0)    收藏  举报