#include <iostream>
using namespace std;
const int N = 100010;
int A[N], B[N], C[N];
int Add(int a[], int b[], int c[], int cnt) {
int t = 0;//t表示进位
for (int i=1; i<=cnt; i++) {
t += a[i] + b[i];//进位加上a和b第i位上的数
c[i] = t % 10;//c的值就是进位的个位数
t /= 10;//把t的个位数去掉只剩下十位数,即只剩下这个位置的进位
}
if (t) c[++cnt] = 1;//如果t==1,表示还有一个进位,要补上
return cnt;
}
int main() {
string a, b;
cin >> a >> b;
//A和B倒着放进int数组,因为有进位,倒着放容易处理
int cnt1 = 0;
for (int i=a.size()-1; i>=0; i--)
A[++cnt1] = a[i] - '0';
int cnt2 = 0;
for (int i=b.size()-1; i>=0; i--)
B[++cnt2] = b[i] - '0';
int tot = Add(A, B, C, max(cnt1, cnt2));
//因为A和B是倒着放的,所以C也要倒着输出
for (int i=tot; i>=1; i--)
cout << C[i];
}
高精度减法加大数优化组合数加高精度乘法
int primes[N], cnt;
bool st[N];
int a[N], b[N]; // C(m+n, n)结果存储在a中, C(m+n, m-1)结果存储在b中
// 筛质数
void init(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) primes[cnt++] = i;
for (int j = 0; primes[j] * i <= n; j++) {
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
// 返回n中质因数p的个数
int get(int n, int p) {
int s = 0;
while (n) s += n / p, n /= p;
return s;
}
// 高精度乘法
void mul(int r[], int &len, int x) {
int t = 0;
for (int i = 0; i < len; i++) {
t += r[i] * x;
r[i] = t % 10;
t /= 10;
}
while (t) {
r[len++] = t % 10;
t /= 10;
}
}
// 返回组合数C(x, y),结果存储在r中, r[0]是最低位
int C(int x, int y, int r[]) {
int len = 1;
r[0] = 1;
for (int i = 0; i < cnt; i++) {
int p = primes[i];
int s = get(x, p) - get(y, p) - get(x - y, p);
while (s--) mul(r, len, p);
}
return len;
}
// 高精度减法
void sub(int a[], int al, int b[], int bl) {
for (int i = 0, t = 0; i < al; i++) {
a[i] -= t + b[i];
if (a[i] < 0) a[i] += 10, t = 1;
else t = 0;
}
}
int main() {
init(N - 1);
int n, m;
cin >> n >> m;
// 求出C(m+n, n)结果存储在a中, C(m+n, m-1)结果存储在b中
int al = C(n + m, m, a); // al是数据a的长度
int bl = C(n + m, m - 1, b); // bl是数据b的长度
// C(m+n, n) - C(m+n, m-1),结果存储在a中
sub(a, al, b, bl);// (a的数组,a的长度,b数组,b的长度)
///下面输出大数 a
int k = al - 1;
while (!a[k]) k--;
while (k >= 0) printf("%d", a[k--]);
return 0;
}