You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
1.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
int primes[N], cnt;
bool st[N];
// 欧拉筛
void get_primes(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) primes[cnt++] = i;
for (int j = 0; primes[j] <= n / i; j++) {
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
// 高精乘低精
void mul(int a[], int &al, int b) {
int t = 0;
for (int i = 1; i <= al; i++) {
t += a[i] * b;
a[i] = t % 10;
t /= 10;
}
while (t) {
a[++al] = t % 10;
t /= 10;
}
}
/**
* 功能n的阶乘中包含的质因子p的个数
* @param n n的阶乘
* @param p 质因子p
* @return 有多少个
*/
int get(int n, int p) {
int cnt = 0;
while (n) { // p^1的个数p^2的个数,p^3的个数...
cnt += n / p;
n /= p;
}
return cnt;
}
// C(a,b)的结果高精度保存到c数组同时返回c数组的长度len
void C(int a, int b, int c[], int &cl) {
// 乘法的基数是1
c[1] = 1, cl = 1; // 由于高精度数组中只有一位是1所以长度也是1
for (int i = 0; i < cnt; i++) { // 枚举区间内所有质数
int p = primes[i];
/*
C(a,b)=a!/(b! * (a-b)!)
a!中有多少个质数因子p
减去(a-b)!的多少个质数因子p,
再减去b!的质数因子p的个数就是总个数
s记录了p这个质数因子出现的次数
*/
int s = get(a, p) - get(b, p) - get(a - b, p);
while (s--) mul(c, cl, p); // 不断的乘p,结果保存到数组c中。len将带回c的有效长度
}
}
int a, b;
int c[N], cl;
int main() {
cin >> a >> b;
// 筛质数
get_primes(N - 1);
// 计算组合数
C(a, b, c, cl);
// 输出高精度结果
for (int i = cl; i >= 1; i--) printf("%d", c[i]);
return 0;
}