[模板] 高精度组合数
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int maxn = 1e6 + 10;
struct bign{
int cnt, num[1010];
bign(int x = 0){
cnt = 0;
memset(num,0,sizeof num);
do{
num[++cnt] = x%10;
x /= 10;
}while(x);
}
bign operator * (const bign& b){
bign t;
t.cnt = cnt + b.cnt;
for(int i = 1; i <= cnt; i++){
for(int j = 1; j <= b.cnt; j++){
t.num[i+j-1] += num[i]*b.num[j];
t.num[i+j] += t.num[i+j-1]/10;
t.num[i+j-1] %= 10;
}
}
while(t.cnt > 1 && t.num[t.cnt] == 0) t.cnt--;
return t;
}
void print(){
for(int i = cnt; i >= 1; i--) printf("%d",num[i]);
puts("");
}
};
int p[maxn],cnt;
bool isp[maxn];
void getp(){
isp[1] = 1;
for(int i = 2; i < maxn; i++){
if(!isp[i]) p[++cnt] = i;
for(int j = 1; j <= cnt && i*p[j] < maxn; j++){
isp[i*p[j]] = 1;
if(i%p[j] == 0) break;
}
}
}
inline int get(int x, int p){
int ans = 0;
while(x){
ans += x/p;
x /= p;
}
return ans;
}
template<class T>
inline T qpow(T& a, int b){
T ans = T(1), base = a;
while(b){
if(b&1) ans = ans*base;
base = base*base, b >>= 1;
}
return ans;
}
inline bign C(int a, int b){
bign ans = bign(1);
for(int i = 1; p[i] <= a; i++) ans = ans*qpow(p[i],get(a,p[i])-get(b,p[i])-get(a-b,p[i]));
return ans;
}
inline bign C(int a, vector<int> b){
bign ans = bign(1);
for(int i = 1; p[i] <= a; i++){
int tmp = get(a,p[i]);
for(auto& u : b) tmp -= get(u,p[i]);
ans = ans*qpow(p[i],tmp);
}
return ans;
}
int a,b;
int main()
{
getp();
scanf("%d%d",&a,&b);
C(a,b).print();
C(a,{2,2}).print();
return 0;
}