0%

『洛谷』高精度

高精度

在 C++ 中,long long 都无法表示我们需要的整数时怎么办?那就用高精度吧!

在 C++ 中,long long 都无法表示我们需要的整数时怎么办?那就用 Python 吧🤣

好吧,高精度对 Python 没有意义,所以该篇中禁用 Python 和 Java 自带的高精度(这些高精度的题目利用 Python 均能一行解决,这没意义)。

五道题,包括加减乘除四项基本运算,最后一题算是应用题吧


完整代码

下面是完整的高精度代码,包含加减乘除,除了减法结果以外均不考虑负数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

class number {
public:
string num; // 记录数值
bool neg = false; // 是否是负数
number(string &n) {
num = n;
}
number(long long n) {
num = to_string(n);
}

number(int n) {
num = to_string(n);
}

string get() {
return num;
}

// 输出流
friend ostream &operator<<(ostream&, const number&);
// 加法
friend number operator+(const number&, const number&);
// 小于号
friend bool operator<(const number&, const number&);
// 减法,结果可能是负数
friend number operator-(const number&, const number&);
// 个位数的乘法
friend number operator*(const number&, const int);
// 乘法,不考虑负数
friend number operator*(const number&, const number&);
// 除法,不考虑负数,只保留整数部分
friend number operator/(const number&, const number&);
};

ostream &operator<<(ostream &out, const number &a) {
if (a.neg) out << '-';
out << a.num;
return out;
}

number operator+(const number &a, const number &b) {
// 加法, 不考虑负数
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
int c = 0; // 进位标志
while (x != a.num.rend() || y != b.num.rend() || c > 0) {
if (x != a.num.rend()) {
c += (*x) - '0'; ++x;
}
if (y != b.num.rend()) {
c += (*y) - '0'; ++y;
}
ss << c % 10;
c /= 10;
}
string ans = ss.str();
// 结果是反的,要逆过来存下
reverse(ans.begin(), ans.end());
return number(ans);
}

bool operator<(const number &a, const number &b) {
// 比较大小,不考虑负数
int n1 = a.num.size(), n2 = b.num.size();
if (n1 != n2) return n1 < n2;
for (auto x = a.num.begin(), y = b.num.begin(); x != a.num.end(); ++x, ++y) {
if ((*x) != (*y)) return (*x) < (*y);
}
return false; // 不考虑等于
}

bool operator>=(const number &a, const number &b) {
// 比较大小,不考虑负数
int n1 = a.num.size(), n2 = b.num.size();
if (n1 != n2) return n1 > n2;
for (auto x = a.num.begin(), y = b.num.begin(); x != a.num.end(); ++x, ++y) {
if ((*x) != (*y)) return (*x) > (*y);
}
return true; // 考虑等于
}

number operator-(const number &a, const number &b) {
// 减法,结果可能是负数
if (a < b) {
auto ans = b - a;
ans.neg = true;
return ans;
}
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
// 借位标志 c
for (int c = 0; x != a.num.rend(); ++x) {
c = (*x) - '0' - c;
if (y != b.num.rend()) {
c -= (*y) - '0'; ++y;
}
ss << (c + 10) % 10;
if (c < 0) c = 1;
else c = 0;
}
string ans = ss.str();
while (ans.back() == '0') ans.pop_back();
reverse(ans.begin(), ans.end());
if (ans.size() == 0) return number(0);
return number(ans);
}

number operator*(const number &a, const int b) {
// 与个位数的乘法
if (b == 0) return number(0);
stringstream ss;
int c = 0; // 进位标志
for (auto x = a.num.rbegin(); x != a.num.rend() || c != 0; c /= 10) {
if (x != a.num.rend()){
c = (*x - '0') * b + c; ++x;
}
ss << c % 10;
}
string ans = ss.str();
reverse(ans.begin(), ans.end());
return number(ans);
}

number operator*(const number &a, const number &b) {
// 高精度乘法,不考虑负数
number ans(0);
int cnt = 0; // 移位标志
for (auto x = b.num.rbegin(); x != b.num.rend(); ++x, ++cnt) {
auto tmp = a * (*x - '0');
if (tmp.num == "0") continue; // 0 不需要处理
for (int i = 0; i < cnt; ++i) tmp.num.push_back('0');
ans = ans + tmp;
}
return ans;
}

number operator/(const number &a, const number &b) {
// 高精度除法,只保留整数部分,不考虑负数
if (a < b) return number(0);
string tmp = a.num.substr(0, b.num.size());
number base(tmp);
stringstream ss;
for (auto x = a.num.begin() + b.num.size(); ; x++) {
int cnt = 0;
while (base >= b * (cnt + 1)) ++cnt;
ss << cnt;
if (x == a.num.end()) break;
base = base - (b * cnt);
if (base.num == "0") base.num = *x;
else base.num.push_back(*x);
}
string ans = ss.str();
// 去掉前置 0
reverse(ans.begin(), ans.end());
while (ans.back() == '0') ans.pop_back();
reverse(ans.begin(), ans.end());
return number(ans);
}

int main() {
string a, b;
cin >> a >> b;
// P1601 高精度加法
cout << number(a) + number(b) << '\n';
// P2142 高精度减法
cout << number(a) - number(b) << '\n';
// 1303 高精度乘法
cout << number(a) * number(b) << '\n';
// 1480 高精度除法
cout << number(a) / number(b) << '\n';
return 0;
}

P1601 A+B Problem(高精)

题目描述

高精度加法,相当于 a+b problem,不用考虑负数

输入格式

分两行输入。\(a,b \leq 10^{500}\)

输出格式

输出只有一行,代表 \(a+b\) 的值。

样例 #1

样例输入 #1

1
2
1
1

样例输出 #1

1
2

样例 #2

样例输入 #2

1
2
1001
9099

样例输出 #2

1
10100

解题思路

用字符串或者字符数组存数然后手动加减即可

解答代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <cstdio>
#include <iostream>
#include <cstdlib>
using namespace std;

void redir() {
std::ios::sync_with_stdio(false);
// std::cin.tie(0);
// std::cout.tie(0);
// freopen("luogu.in", "r", stdin);
// freopen("out.txt", "w", stdout);
}

const int N = 555;
char a[N], b[N], c[N];

int read(char *s) {
int i = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
for (; c >= '0' && c <= '9'; c = getchar()) s[i++] = c;
return i;
}

void rev(char *s, int n) {
char tmp;
for (int i = 0, j = n - 1; i < j; ++i, --j) {
tmp = s[i]; s[i] = s[j]; s[j] = tmp;
}
}

int add(char *s1, int n1, char *s2, int n2, char *s3) {
// 将长度为 n1, n2 的 s1, s2 相加,结果放在 s3, 返回长度
int f = 0, num, i = 0; // 进位标志
--n1; --n2;
while (n1 >= 0 || n2 >= 0) {
num = (n1 >= 0 ? s1[n1] - '0' : 0) + (n2 >= 0 ? s2[n2] - '0' : 0) + f;
--n1; --n2;
if (num > 9) {
f = 1; num -= 10;
}
else f = 0;
s3[i++] = num + '0';
}
if (f != 0) s3[i++] = f + '0';
rev(s3, i); // 结果是反的,要反一下
return i;
}

int main() {

redir();
int n1 = read(a), n2 = read(b);
int n3 = add(a, n1, b, n2, c);
for (int i = 0; i < n3; ++i) putchar(c[i]);
return 0;
}


P2142 高精度减法

题目描述

高精度减法。

输入格式

两个整数 \(a,b\)(第二个可能比第一个大)。

输出格式

结果(是负数要输出负号)。

样例 #1

样例输入 #1

1
2
2
1

样例输出 #1

1
1

提示

  • \(20\%\) 数据 \(a,b\) 在 long long 范围内;
  • \(100\%\) 数据 \(0<a,b\le 10^{10086}\)

解题思路

模拟下竖式减法,注意几个坑点就是了。一是要去掉多余的前导零,二是结果为 0 时别清空了

解答代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <cstdio>
#include <iostream>
using namespace std;

void redir() {
std::ios::sync_with_stdio(false);
}

const int N = 12000;
char a[N], b[N], c[N];

int read(char *s) {
int i = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
for (; c >= '0' && c <= '9'; c = getchar()) s[i++] = c;
return i;
}

void rev(char *s, int n) {
char tmp;
for (int i = 0, j = n - 1; i < j; ++i, --j) {
tmp = s[i]; s[i] = s[j]; s[j] = tmp;
}
}

bool comp(char *s1, int n1, char *s2, int n2) {
// return s1 >= s2
if (n1 != n2) return n1 >= n2;
for (int i = 0; i < n1; ++i) {
if (s1[i] != s2[i]) return s1[i] >= s2[i];
}
return true; // s1 == s2
}

int hp_minus(char *s1, int n1, char *s2, int n2, char *s3) {
int idx = 0, num, f = 0, neg = 0; // f 借位, neg 是否为负数
if (!comp(s1, n1, s2, n2)) {
char* tmp = s1; s1 = s2; s2 = tmp;
neg = n1; n1 = n2; n2 = neg;
neg = 1;
}
for (--n1, --n2; n1 >= 0; --n1, --n2) {
num = s1[n1] - (n2 >= 0 ? s2[n2] : '0') - f;
if (num < 0) {
f = 1; num += 10;
}
else f = 0;
s3[idx++] = num + '0';
}
while (idx > 0 && s3[idx - 1] == '0') --idx;
if (neg == 1 && idx > 0) s3[idx++] = '-';
if (idx == 0) s3[idx++] = '0';
rev(s3, idx);
return idx;
}

int main() {

redir();
int n1 = read(a), n2 = read(b);
int n3 = hp_minus(a, n1, b, n2, c);
for (int i = 0; i < n3; ++i) putchar(c[i]);
return 0;
}

P1303 A*B Problem

题目描述

给出两个非负整数,求它们的乘积。

输入格式

输入共两行,每行一个非负整数。

输出格式

输出一个非负整数表示乘积。

样例 #1

样例输入 #1

1
2
1 
2

样例输出 #1

1
2

提示

每个非负整数不超过 \(10^{2000}\)

解题思路

模拟竖式乘法即可

解答代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

class number {
private:
string num; // 记录数值
bool neg = false; // 是否是负数
public:
number(string &n) {
num = n;
}
number(long long n) {
num = to_string(n);
}

number(int n) {
num = to_string(n);
}

string get() {
return num;
}

// 输出流
friend ostream &operator<<(ostream&, const number&);
// 加法
friend number operator+(const number&, const number&);
// 小于号
friend bool operator<(const number&, const number&);
// 减法,结果可能是负数
friend number operator-(const number&, const number&);
// 个位数的乘法
friend number operator*(const number&, const int);
// 乘法,不考虑负数
friend number operator*(const number&, const number&);
};

ostream &operator<<(ostream &out, const number &a) {
if (a.neg) out << '-';
out << a.num;
return out;
}

number operator+(const number &a, const number &b) {
// 加法, 不考虑负数
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
int c = 0; // 进位标志
while (x != a.num.rend() || y != b.num.rend() || c > 0) {
if (x != a.num.rend()) {
c += (*x) - '0'; ++x;
}
if (y != b.num.rend()) {
c += (*y) - '0'; ++y;
}
ss << c % 10;
c /= 10;
}
string ans = ss.str();
// 结果是反的,要逆过来存下
reverse(ans.begin(), ans.end());
return number(ans);
}

bool operator<(const number &a, const number &b) {
// 比较大小,不考虑负数
int n1 = a.num.size(), n2 = b.num.size();
if (n1 != n2) return n1 < n2;
for (auto x = a.num.begin(), y = b.num.begin(); x != a.num.end(); ++x, ++y) {
if ((*x) != (*y)) return (*x) < (*y);
}
return false; // 不考虑等于
}


number operator-(const number &a, const number &b) {
// 减法,结果可能是负数
if (a < b) {
auto ans = b - a;
ans.neg = true;
return ans;
}
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
// 借位标志 c
for (int c = 0; x != a.num.rend(); ++x) {
c = (*x) - '0' - c;
if (y != b.num.rend()) {
c -= (*y) - '0'; ++y;
}
ss << (c + 10) % 10;
if (c < 0) c = 1;
else c = 0;
}
string ans = ss.str();
while (ans.back() == '0') ans.pop_back();
reverse(ans.begin(), ans.end());
if (ans.size() == 0) return number(0);
return number(ans);
}

number operator*(const number &a, const int b) {
// 与个位数的乘法
if (b == 0) return number(0);
stringstream ss;
int c = 0; // 进位标志
for (auto x = a.num.rbegin(); x != a.num.rend() || c != 0; c /= 10) {
if (x != a.num.rend()){
c = (*x - '0') * b + c; ++x;
}
ss << c % 10;
}
string ans = ss.str();
reverse(ans.begin(), ans.end());
return number(ans);
}

number operator*(const number &a, const number &b) {
// 高精度乘法
number ans(0);
int cnt = 0; // 移位标志
for (auto x = b.num.rbegin(); x != b.num.rend(); ++x, ++cnt) {
auto tmp = a * (*x - '0');
if (tmp.num == "0") continue;
for (int i = 0; i < cnt; ++i) tmp.num.push_back('0');
ans = ans + tmp;
}
return ans;
}


int main() {
string a, b;
cin >> a >> b;
// 1301 高精度乘法
cout << number(a) * number(b) << '\n';
return 0;
}

P1480 A/B Problem

题目描述

输入两个整数 \(a,b\),输出它们的商。

输入格式

两行,第一行是被除数,第二行是除数。

输出格式

一行,商的整数部分。

样例 #1

样例输入 #1

1
2
10
2

样例输出 #1

1
5

提示

\(0\le a\le 10^{5000}\)\(1\le b\le 10^9\)

解题思路

模拟竖式除法即可

解答代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

class number {
public:
string num; // 记录数值
bool neg = false; // 是否是负数
number(string &n) {
num = n;
}
number(long long n) {
num = to_string(n);
}

number(int n) {
num = to_string(n);
}

string get() {
return num;
}

// 输出流
friend ostream &operator<<(ostream&, const number&);
// 加法
friend number operator+(const number&, const number&);
// 小于号
friend bool operator<(const number&, const number&);
// 减法,结果可能是负数
friend number operator-(const number&, const number&);
// 个位数的乘法
friend number operator*(const number&, const int);
// 乘法,不考虑负数
friend number operator*(const number&, const number&);
// 除法,不考虑负数,只保留整数部分
friend number operator/(const number&, const number&);
};

ostream &operator<<(ostream &out, const number &a) {
if (a.neg) out << '-';
out << a.num;
return out;
}

number operator+(const number &a, const number &b) {
// 加法, 不考虑负数
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
int c = 0; // 进位标志
while (x != a.num.rend() || y != b.num.rend() || c > 0) {
if (x != a.num.rend()) {
c += (*x) - '0'; ++x;
}
if (y != b.num.rend()) {
c += (*y) - '0'; ++y;
}
ss << c % 10;
c /= 10;
}
string ans = ss.str();
// 结果是反的,要逆过来存下
reverse(ans.begin(), ans.end());
return number(ans);
}

bool operator<(const number &a, const number &b) {
// 比较大小,不考虑负数
int n1 = a.num.size(), n2 = b.num.size();
if (n1 != n2) return n1 < n2;
for (auto x = a.num.begin(), y = b.num.begin(); x != a.num.end(); ++x, ++y) {
if ((*x) != (*y)) return (*x) < (*y);
}
return false; // 不考虑等于
}

bool operator>=(const number &a, const number &b) {
// 比较大小,不考虑负数
int n1 = a.num.size(), n2 = b.num.size();
if (n1 != n2) return n1 > n2;
for (auto x = a.num.begin(), y = b.num.begin(); x != a.num.end(); ++x, ++y) {
if ((*x) != (*y)) return (*x) > (*y);
}
return true; // 考虑等于
}


number operator-(const number &a, const number &b) {
// 减法,结果可能是负数
if (a < b) {
auto ans = b - a;
ans.neg = true;
return ans;
}
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
// 借位标志 c
for (int c = 0; x != a.num.rend(); ++x) {
c = (*x) - '0' - c;
if (y != b.num.rend()) {
c -= (*y) - '0'; ++y;
}
ss << (c + 10) % 10;
if (c < 0) c = 1;
else c = 0;
}
string ans = ss.str();
while (ans.back() == '0') ans.pop_back();
reverse(ans.begin(), ans.end());
if (ans.size() == 0) return number(0);
return number(ans);
}

number operator*(const number &a, const int b) {
// 与个位数的乘法
if (b == 0) return number(0);
stringstream ss;
int c = 0; // 进位标志
for (auto x = a.num.rbegin(); x != a.num.rend() || c != 0; c /= 10) {
if (x != a.num.rend()){
c = (*x - '0') * b + c; ++x;
}
ss << c % 10;
}
string ans = ss.str();
reverse(ans.begin(), ans.end());
return number(ans);
}

number operator*(const number &a, const number &b) {
// 高精度乘法,不考虑负数
number ans(0);
int cnt = 0; // 移位标志
for (auto x = b.num.rbegin(); x != b.num.rend(); ++x, ++cnt) {
auto tmp = a * (*x - '0');
if (tmp.num == "0") continue; // 0 不需要处理
for (int i = 0; i < cnt; ++i) tmp.num.push_back('0');
ans = ans + tmp;
}
return ans;
}

number operator/(const number &a, const number &b) {
// 高精度除法,只保留整数部分,不考虑负数
if (a < b) return number(0);
string tmp = a.num.substr(0, b.num.size());
number base(tmp);
stringstream ss;
for (auto x = a.num.begin() + b.num.size(); ; x++) {
int cnt = 0;
while (base >= b * (cnt + 1)) ++cnt;
ss << cnt;
if (x == a.num.end()) break;
base = base - (b * cnt);
if (base.num == "0") base.num = *x;
else base.num.push_back(*x);
}
string ans = ss.str();
// 去掉前置 0
reverse(ans.begin(), ans.end());
while (ans.back() == '0') ans.pop_back();
reverse(ans.begin(), ans.end());
return number(ans);
}

int main() {
string a, b;
cin >> a >> b;
// 1480 高精度除法
cout << number(a) / number(b) << '\n';
return 0;
}

P1009 [NOIP1998 普及组] 阶乘之和

题目描述

用高精度计算出 \(S = 1! + 2! + 3! + \cdots + n!\)\(n \le 50\))。

其中 ! 表示阶乘,定义为 \(n!=n\times (n-1)\times (n-2)\times \cdots \times 1\)。例如,\(5! = 5 \times 4 \times 3 \times 2 \times 1=120\)

输入格式

一个正整数 \(n\)

输出格式

一个正整数 \(S\),表示计算结果。

样例 #1

样例输入 #1

1
3

样例输出 #1

1
9

提示

【数据范围】

对于 \(100 \%\) 的数据,\(1 \le n \le 50\)

【其他说明】

注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 \(n \le 20\),使用书中的代码无法通过本题。

如果希望通过本题,请继续学习第八章高精度的知识。

解题思路

很简单的应用题

解答代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

class number {
public:
string num; // 记录数值
bool neg = false; // 是否是负数
number(string &n) {
num = n;
}
number(long long n) {
num = to_string(n);
}

number(int n) {
num = to_string(n);
}

string get() {
return num;
}

// 输出流
friend ostream &operator<<(ostream&, const number&);
// 加法
friend number operator+(const number&, const number&);
// 个位数的乘法
friend number operator*(const number&, const int);
// 乘法,不考虑负数
friend number operator*(const number&, const number&);
};

ostream &operator<<(ostream &out, const number &a) {
if (a.neg) out << '-';
out << a.num;
return out;
}

number operator+(const number &a, const number &b) {
// 加法, 不考虑负数
stringstream ss;
auto x = a.num.rbegin(), y = b.num.rbegin();
int c = 0; // 进位标志
while (x != a.num.rend() || y != b.num.rend() || c > 0) {
if (x != a.num.rend()) {
c += (*x) - '0'; ++x;
}
if (y != b.num.rend()) {
c += (*y) - '0'; ++y;
}
ss << c % 10;
c /= 10;
}
string ans = ss.str();
// 结果是反的,要逆过来存下
reverse(ans.begin(), ans.end());
return number(ans);
}

number operator*(const number &a, const int b) {
// 与个位数的乘法
if (b == 0) return number(0);
stringstream ss;
int c = 0; // 进位标志
for (auto x = a.num.rbegin(); x != a.num.rend() || c != 0; c /= 10) {
if (x != a.num.rend()){
c = (*x - '0') * b + c; ++x;
}
ss << c % 10;
}
string ans = ss.str();
reverse(ans.begin(), ans.end());
return number(ans);
}

number operator*(const number &a, const number &b) {
// 高精度乘法,不考虑负数
number ans(0);
int cnt = 0; // 移位标志
for (auto x = b.num.rbegin(); x != b.num.rend(); ++x, ++cnt) {
auto tmp = a * (*x - '0');
if (tmp.num == "0") continue; // 0 不需要处理
for (int i = 0; i < cnt; ++i) tmp.num.push_back('0');
ans = ans + tmp;
}
return ans;
}

number factorial(long long n) {
// 计算 n 的阶乘,应用高精度乘法和加法即可
number ans(1), cnt(1);
for (long long i = 2; i <= n; ++i) {
cnt = cnt * number(i);
ans = ans + cnt;
}
return ans;
}

int main() {
// 阶乘
long long n;
cin >> n;
cout << factorial(n);
return 0;
}
--- ♥ end ♥ ---

欢迎关注我呀~