头文件和常用函数

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
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
#define int ll

inline ll read() {
ll x = 0, f = 0; char c = getchar();
while (c > 57 || c < 48) f |= c == 45, c = getchar();
while (c <= 57 && c >= 48) x = (x << 3) + (x << 1) + c - 48, c = getchar();
return f ? -x : x;
}

ll qpow(ll a, ll n) {
ll res = 1;
while (n) {
if (n & 1) res = res * a % mod;
a = a * a % mod;
n >>= 1;
}
return res;
}

ll ceil(ll n, ll m) {
if (n >= 0) return (n + m - 1) / m;
else return n / m;
}

ll floor(ll n, ll m) {
if (n >= 0) return n / m;
else return (n - m + 1) / m;
}

template<class T>
T sqrt(T n) {
    T lo = 0, hi = n;
    while (lo <= hi) {
        T mid = (lo + hi) / 2;
        if (mid * mid == n) return mid;
        else if (mid * mid < n) lo = mid + 1;
        else hi = mid - 1;
    }
    return hi;
}

int __lg(ll x) {
int res = 0;
while (x >>= 1) ++res;
return res;
}

template<class T>
void chmax(T &a, T b) {
if (a < b) {
a = b;
}
}

template<class T>
T gcd(T a, T b) {
return b ? gcd(b, a % b) : a;
}

文件读入输出 + 计时器

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
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

ifstream fin("in.txt");
streambuf* pOldIn = cin.rdbuf(fin.rdbuf());

ofstream fout("out.txt");
streambuf* pOldOut = cout.rdbuf(fout.rdbuf());

FILE* filein = fopen("in.txt", "r");
freopen("in.txt", "r", stdin);
FILE* fileout = fopen("out.txt", "w");
freopen("out.txt", "w", stdout);

int T;
cin >> T;
int now = clock();
for (int i = 1; i <= T; ++i) {
int st = clock();
eachT();
cerr << "Case#" << i << " finished in " << clock() - st << "ms\n";
}
cerr << "Finished in " << clock() - now << "ms\n";

return 0;
}

文件比对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def compare_files(file1, file2):
with open(file1, 'r', encoding='utf-8') as f, open(file2, 'r', encoding='utf-8') as g:
for l, (h, k) in enumerate(zip(f, g), 1):
h = h.rstrip()
k = k.rstrip()
if h != k:
# 找到第一个不同的字符
for c, (char1, char2) in enumerate(zip(h, k), 1):
if char1 != char2:
return f"Declined! L{l}, C{c}"
return f"Declined! L{l}"
if f.readline() or g.readline():
return "Declined!"

return "Accepted!"
print(compare_files('1.txt', '2.txt'))

随机数

1
2
3
#include <chrono>
#include <random>
mt19937_64 rng{ (unsigned long long)chrono::steady_clock::now().time_since_epoch().count() };

i128

1
2
3
4
5
6
7
8
9
10
11
using i128 = __int128;

ostream &operator<<(ostream &os, i128 n) {
string s;
while (n) {
s += '0' + n % 10;
n /= 10;
}
reverse(s.begin(), s.end());
return os << s;
}

取模类 A(新,支持非固定模数)

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
template<class T> constexpr T qpow(T a, ll n) {
T res{ 1 };
for (; n; n /= 2, a *= a) {
if (n % 2) res *= a;
}
return res;
}
constexpr ll mul(ll a, ll b, ll p) {
ll res = a * b - ll(1.L * a * b / p) * p;
res %= p;
if (res < 0) res += p;
return res;
}
template<ll m> struct mint {
ll x;
constexpr mint() : x{ 0 } {}
constexpr mint(ll x) : x{ norm(x % getMod()) } {}

static ll M;
constexpr static ll getMod() { return m > 0 ? m : M; }
constexpr static void setMod(ll MM) { M = MM; }
constexpr ll norm(ll x) const {
if (x < 0) x += getMod();
if (x >= getMod()) x -= getMod();
return x;
}
constexpr ll val() const { return x; }
constexpr mint operator-() const {
mint res;
res.x = norm(getMod() - x);
return res;
}
constexpr mint inv() const {
return qpow(*this, getMod() - 2);
}
constexpr mint& operator*=(mint o)& {
if (getMod() < (1ULL << 31)) x = x * o.x % int(getMod());
else x = mul(x, o.x, getMod());
return *this;
}
constexpr mint& operator+=(mint o)& {
x = norm(x + o.x);
return *this;
}
constexpr mint& operator-=(mint o)& {
x = norm(x - o.x);
return *this;
}
constexpr mint& operator/=(mint o)& {
return *this *= o.inv();
}
friend constexpr mint operator*(mint x, mint o) {
mint res = x;
res *= o;
return res;
}
friend constexpr mint operator+(mint x, mint o) {
mint res = x;
res += o;
return res;
}
friend constexpr mint operator-(mint x, mint o) {
mint res = x;
res -= o;
return res;
}
friend constexpr mint operator/(mint x, mint o) {
mint res = x;
res /= o;
return res;
}
friend constexpr istream& operator>>(istream& is, mint& x) {
ll v;
is >> v;
x = mint(v);
return is;
}
friend constexpr ostream& operator<<(ostream& os, const mint& x) {
return os << x.val();
}
friend constexpr bool operator==(mint x, mint o) {
return x.val() == o.val();
}
friend constexpr bool operator!=(mint x, mint o) {
return x.val() != o.val();
}
};
template<> ll mint<0>::M = 998244353;
using Z = mint<998244353>;

struct Comb {
int n;
vector<Z> _fac;
vector<Z> _invfac;
vector<Z> _inv;

Comb() : n{0}, _fac{1}, _invfac{1}, _inv{0} {}
Comb(int n) : Comb() {
init(n);
}

void init(int m) {
m = min(m, int(Z::getMod()) - 1);
if (m <= n) return;
_fac.resize(m + 1);
_invfac.resize(m + 1);
_inv.resize(m + 1);

for (int i = n + 1; i <= m; i++) {
_fac[i] = _fac[i - 1] * i;
}
_invfac[m] = _fac[m].inv();
for (int i = m; i > n; i--) {
_invfac[i - 1] = _invfac[i] * i;
_inv[i] = _invfac[i] * _fac[i - 1];
}
n = m;
}

Z fac(int m) {
if (m > n) init(2 * m);
return _fac[m];
}
Z invfac(int m) {
if (m > n) init(2 * m);
return _invfac[m];
}
Z inv(int m) {
if (m > n) init(2 * m);
return _inv[m];
}
Z C(int n, int m) {
if (n < m || m < 0) return 0;
return fac(n) * invfac(m) * invfac(n - m);
}
} comb;

int main() {
int n, p;
cin >> n >> p;

Z::setMod(p);
}

取模类 B(Binomial 任意模数计算)

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
vector<pair<int, int>> factorize(int n) {
vector<pair<int, int>> factors;
for (int i = 2; static_cast<long long>(i) * i <= n; i++) {
if (n % i == 0) {
int t = 0;
for (; n % i == 0; n /= i)
++t;
factors.emplace_back(i, t);
}
}
if (n > 1)
factors.emplace_back(n, 1);
return factors;
}
constexpr int power(int base, i64 exp) {
int res = 1;
for (; exp > 0; base *= base, exp /= 2) {
if (exp % 2 == 1) {
res *= base;
}
}
return res;
}
constexpr int power(int base, i64 exp, int mod) {
int res = 1 % mod;
for (; exp > 0; base = 1LL * base * base % mod, exp /= 2) {
if (exp % 2 == 1) {
res = 1LL * res * base % mod;
}
}
return res;
}
int inverse(int a, int m) {
int g = m, r = a, x = 0, y = 1;
while (r != 0) {
int q = g / r;
g %= r;
swap(g, r);
x -= q * y;
swap(x, y);
}
return x < 0 ? x + m : x;
}
int solveModuloEquations(const vector<pair<int, int>> &e) {
int m = 1;
for (size_t i = 0; i < e.size(); i++) {
m *= e[i].first;
}
int res = 0;
for (size_t i = 0; i < e.size(); i++) {
int p = e[i].first;
res = (res + 1LL * e[i].second * (m / p) * inverse(m / p, p)) % m;
}
return res;
}
constexpr int N = 1E5;
class Binomial {
const int mod;
private:
const vector<pair<int, int>> factors;
vector<int> pk;
vector<vector<int>> prod;
static constexpr i64 exponent(i64 n, int p) {
i64 res = 0;
for (n /= p; n > 0; n /= p) {
res += n;
}
return res;
}
int product(i64 n, size_t i) {
int res = 1;
int p = factors[i].first;
for (; n > 0; n /= p) {
res = 1LL * res * power(prod[i].back(), n / pk[i], pk[i]) % pk[i] * prod[i][n % pk[i]] % pk[i];
}
return res;
}
public:
Binomial(int mod) : mod(mod), factors(factorize(mod)) {
pk.resize(factors.size());
prod.resize(factors.size());
for (size_t i = 0; i < factors.size(); i++) {
int p = factors[i].first;
int k = factors[i].second;
pk[i] = power(p, k);
prod[i].resize(min(N + 1, pk[i]));
prod[i][0] = 1;
for (int j = 1; j < prod[i].size(); j++) {
if (j % p == 0) {
prod[i][j] = prod[i][j - 1];
} else {
prod[i][j] = 1LL * prod[i][j - 1] * j % pk[i];
}
}
}
}
int operator()(i64 n, i64 m) {
if (n < m || m < 0) {
return 0;
}
vector<pair<int, int>> ans(factors.size());
for (int i = 0; i < factors.size(); i++) {
int p = factors[i].first;
int k = factors[i].second;
int e = exponent(n, p) - exponent(m, p) - exponent(n - m, p);
if (e >= k) {
ans[i] = make_pair(pk[i], 0);
} else {
int pn = product(n, i);
int pm = product(m, i);
int pd = product(n - m, i);
int res = 1LL * pn * inverse(pm, pk[i]) % pk[i] * inverse(pd, pk[i]) % pk[i] * power(p, e) % pk[i];
ans[i] = make_pair(pk[i], res);
}
}
return solveModuloEquations(ans);
}
};

取模类(旧)

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
template<const int T>
struct ModInt {
const static int _mod = T;
int x;
ModInt(int x = 0) : x((x + _mod) % _mod) {}
ModInt(ll x) : x(int((x + _mod) % _mod)) {}
int vale() { return x; }
ModInt operator + (const ModInt& a) const { int b = x + a.x; return ModInt(b < _mod ? b : b - _mod); }
ModInt operator - (const ModInt& a) const { int b = x - a.x; return ModInt(b < 0 ? b + _mod : b); }
ModInt operator * (const ModInt& a) const { return ModInt(1LL * x * a.x % _mod); }
ModInt operator / (const ModInt& a) const { return *this * a.inv(); }
bool operator == (const ModInt& a) const { return x == a.x; };
bool operator != (const ModInt& a) const { return x != a.x; };
void operator += (const ModInt& a) { x += a.x; if (x >= _mod) x -= _mod; }
void operator -= (const ModInt& a) { x -= a.x; if (x < 0) x += _mod; }
void operator *= (const ModInt& a) { x = 1LL * x * a.x % _mod; }
void operator /= (const ModInt& a) { *this = *this / a; }
friend ModInt operator + (int _y, const ModInt& a) { int b = _y + a.x; return ModInt(b < _mod ? b : b - _mod); }
friend ModInt operator - (int _y, const ModInt& a) { int b = _y - a.x; return ModInt(b < 0 ? b + _mod : b); }
friend ModInt operator * (int _y, const ModInt& a) { return ModInt(1LL * _y * a.x % _mod); }
friend ModInt operator / (int _y, const ModInt& a) { return ModInt(_y) / a; }
friend ostream& operator<<(ostream& os, const ModInt& a) { return os << a.x; }
friend istream& operator>>(istream& is, ModInt& _t) { return is >> _t.x; }
ModInt operator ^ (ll n) const {
if (n == 0) return 1;
ModInt _r(1), a(x);
while (n) {
if (n & 1) _r *= a;
a *= a;
n >>= 1;
}
return _r;
}
ModInt inv() const {
int a = x, b = _mod, _u = 1, _v = 0;
while (b) {
int _t = a / b;
a -= _t * b; swap(a, b);
_u -= _t * _v; swap(_u, _v);
}
if (_u < 0) _u += _mod;
return _u;
}
};
using Z = ModInt<1000000007>;
using Z = ModInt<998244353>;

分数类

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
struct Frac {
int fz, fm;
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}

Frac(int fz = 0, int fm = 1) : fz(fz), fm(fm) {
int d = gcd(fz, fm);
this->fz /= d;
this->fm /= d;
}

Frac operator+(const Frac& b) const {
return Frac(fz * b.fm + fm * b.fz, fm * b.fm);
}
Frac operator-(const Frac& b) const {
return Frac(fz * b.fm - fm * b.fz, fm * b.fm);
}
Frac operator*(const Frac& b) const {
return Frac(fz * b.fz, fm * b.fm);
}
Frac operator/(const Frac& b) const {
return Frac(fz * b.fm, fm * b.fz);
}

bool operator<(const Frac& b) const {
return fz * b.fm < fm * b.fz;
}
bool operator==(const Frac& b) const {
return fz * b.fm == fm * b.fz;
}
};

矩阵类

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
struct Matrix {
int n;
vector<vector<int>> a;
Matrix(int n) : n(n) { // 初始化
a.resize(n + 1, vector<int>(n + 1, 0));
}

void unit() { // 转化为单位阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j)
a[i][j] = 1;
else
a[i][j] = 0;
}
}
}

Matrix operator*(const Matrix& B) const { // 矩阵乘法
Matrix ans(n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
ans.a[i][j] += a[i][k] * B.a[k][j];
}
}
}
return ans;
}

Matrix operator^(int n) const { // 矩阵快速幂
Matrix ans(n);
ans.unit();
Matrix A = *this;
while (n) {
if (n & 1) {
ans = ans * A;
}
A = A * A;
n >>= 1;
}
return ans;
}

Matrix operator+(const Matrix& B) const { // 矩阵加法
Matrix ans(n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
ans.a[i][j] = a[i][j] + B.a[i][j];
}
}
return ans;
}

Matrix operator-(const Matrix& B) const { // 矩阵减法
Matrix ans(n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
ans.a[i][j] = a[i][j] - B.a[i][j];
}
}
return ans;
}

Matrix operator*(int k) const { // 矩阵数乘
Matrix ans(n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
ans.a[i][j] = a[i][j] * k;
}
}
return ans;
}

void show() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
};

高精度类

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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
namespace Bignum {
struct data {
vector<int> num;
bool op;
data(int sizeT = 0) {
num.resize(sizeT);
op = true;
}
int length() {
return num.size();
}
void clearbackzero() {
while (length() > 1 && num[length() - 1] == 0) {
num.popback();
}
if (length() == 1 && num[0] == 0) {
op = true;
}
}
bool is_zero() {
clearbackzero();
if (!op) return false;
if (length() > 1) return false;
if (num[0]) return false;
return true;
}
void read() {
num.clear();
string s1;
cin >> s1;
if (s1[0] == '-') op = false, s1.erase(0, 1);
for (int i = s1.size() - 1; i >= 0; i--) num.pushback(s1[i] - '0');
return;
}
void print() {
if (op == false) printf("-");
bool flag = false;
for (int i = length() - 1; i >= 0; i--) {
if (num[i] != 0 || flag == true) {
printf("%d", num[i]);
flag = true;
}
}
if (flag == false) printf("0");
}
};
int intws(long long x) {
int t = 0;
while (x) x /= 10, t++;
return t;
}
data numtodata(long long a) {
data ans(intws(a));
if (a < 0) {
a = -a, ans.op = false;
}
if (a == 0) {
ans.clearbackzero();
return ans;
}
for (int i = 0; i < ans.length(); i++) {
ans.num[i] = a % 10, a /= 10;
}
ans.clearbackzero();
return ans;
}
bool operator>(data a, data b) {
a.clearbackzero();
b.clearbackzero();
if (a.op == true && b.op == true) {
if (a.length() > b.length()) return true;
else if (a.length() < b.length()) return false;
else {
for (int i = a.length() - 1; i >= 0; i--) {
if (a.num[i] > b.num[i]) return true;
if (a.num[i] < b.num[i]) return false;
}
return false;
}
}
if (a.op == true && b.op == false) return true;
if (a.op == false && b.op == true) return false;
if (a.op == false && b.op == false) {
if (a.length() > b.length()) return false;
else if (a.length() < b.length()) return true;
else {
for (int i = a.length() - 1; i >= 0; i--) {
if (a.num[i] > b.num[i]) return false;
if (a.num[i] < b.num[i]) return true;
}
return false;
}
}
return true;
}
bool operator<(data a, data b) {
a.clearbackzero();
b.clearbackzero();
if (a.op == true && b.op == true) {
if (a.length() > b.length()) return false;
else if (a.length() < b.length()) return true;
else {
for (int i = a.length() - 1; i >= 0; i--) {
if (a.num[i] > b.num[i]) return false;
if (a.num[i] < b.num[i]) return true;
}
return false;
}
}
if (a.op == true && b.op == false) return false;
if (a.op == false && b.op == true) return true;
if (a.op == false && b.op == false) {
if (a.length() > b.length()) return true;
else if (a.length() < b.length()) return false;
else {
for (int i = a.length() - 1; i >= 0; i--) {
if (a.num[i] > b.num[i]) return true;
if (a.num[i] < b.num[i]) return false;
}
return false;
}
}
return true;
}
bool operator==(data a, data b) {
a.clearbackzero();
b.clearbackzero();
if (a.op != b.op) return false;
if (a.length() != b.length()) return false;
for (int i = 0; i < a.length(); i++)
if (a.num[i] != b.num[i]) return false;
return true;
}
bool operator>=(data a, data b) {
return (a > b) || (a == b);
}
bool operator<=(data a, data b) {
return (a < b) || (a == b);
}
bool operator!=(data a, data b) {
return !(a == b);
}
data operator-(data a) {
a.op = !a.op;
if ((a.length()) == 1 && a.num[0] == 0) a.op = true;
return a;
}
data abs(data a) {
a.op = true;
return a;
}
data operator+(data a, data b) {
if (abs(a) < abs(b)) {
return b + a;
}
data ANS(a.length() + 1);
ANS.op = a.op;
if (a.op == true && b.op == true) {
for (int i = 0; i < ANS.length() - 1; i++) {
ANS.num[i] += a.num[i] + ((i < b.length()) ? (b.num[i]) : 0);
if (ANS.num[i] >= 10) {
ANS.num[i + 1] += 1;
ANS.num[i] -= 10;
}
}
}
if (a.op == true && b.op == false) {
for (int i = 0; i < ANS.length() - 1; i++) {
ANS.num[i] += a.num[i] - ((i < b.length()) ? (b.num[i]) : 0);
if (ANS.num[i] < 0) {
ANS.num[i + 1] -= 1;
ANS.num[i] += 10;
}
}
}
if (a.op == false && b.op == true) {
for (int i = 0; i < ANS.length() - 1; i++) {
ANS.num[i] += a.num[i] - ((i < b.length()) ? (b.num[i]) : 0);
if (ANS.num[i] < 0) {
ANS.num[i + 1] -= 1;
ANS.num[i] += 10;
}
}
}
if (a.op == false && b.op == false) {
for (int i = 0; i < ANS.length() - 1; i++) {
ANS.num[i] += a.num[i] + ((i < b.length()) ? (b.num[i]) : 0);
if (ANS.num[i] >= 10) {
ANS.num[i + 1] += 1;
ANS.num[i] -= 10;
}
}
}
ANS.clearbackzero();
return ANS;
}
data operator-(data a, data b) {
return a + (-b);
}
data operator*(data a, data b) {
data ans(a.length() + b.length());
ans.op = !(a.op ^ b.op);
for (int i = 0; i < a.length(); i++) {
for (int j = 0; j < b.length(); j++)
ans.num[i + j] += a.num[i] * b.num[j];
}
for (int i = 0; i < ans.length() - 1; i++) {
ans.num[i + 1] += ans.num[i] / 10;
ans.num[i] %= 10;
}
ans.clearbackzero();
return ans;
}
data operator*(data a, int b) {
data ans(a.length() + 20);
ans.op = !(a.op ^ (b > 0));
for (int i = 0; i < a.length(); i++) {
ans.num[i] += a.num[i] * b;
}
for (int i = 0; i < ans.length() - 1; i++) {
ans.num[i + 1] += ans.num[i] / 10;
ans.num[i] %= 10;
}
ans.clearbackzero();
return ans;
}
data operator*(int a, data b) {
return b * a;
}
data numcopy(data a, int l) {
data b(a.length() + l);
for (int i = 0; i < a.length(); i++)
b.num[i + l] = a.num[i];
b.op = a.op;
b.clearbackzero();
return b;
}
data operator/(data a, data b) {
data c(a.length());
bool beginop = a.op;
c.op = !(a.op ^ b.op);
for (int i = c.length() - 1; i >= 0; i--) {
data t = numcopy(b, i);
while (abs(a) >= abs(t)) {
c.num[i]++;
if (a.op == t.op) a = a - t;
else a = a + t;
a.clearbackzero();
}
}
c.clearbackzero();
return c;
}
data operator/(data a, int b) {
data c(a.length());
bool beginop = a.op;
c.op = !(a.op ^ (b > 0));
int r = 0;
for (int i = c.length() - 1; i >= 0; i--) {
r = r * 10 + a.num[i];
c.num[i] = r / b;
r %= b;
}
c.clearbackzero();
return c;
}
data operator%(data a, data b) {
bool beginop = a.op;
for (int i = a.length() - b.length(); i >= 0; i--) {
data t = numcopy(b, i);
while (abs(a) >= abs(t)) {
if (a.op == t.op) a = a - t;
else a = a + t;
a.clearbackzero();
}
}
return a;
}
int operator%(data a, int b) {
data c(a.length());
bool beginop = a.op;
c.op = !(a.op ^ (b > 0));
int r = 0;
for (int i = c.length() - 1; i >= 0; i--) {
r = r * 10 + a.num[i];
c.num[i] = r / b;
r %= b;
}
return r;
}
data operator^(data a, int b) {
data ans(a.length() * b);
ans = numtodata(1);
while (b != 0) {
if (b & 1) ans = ans * a;
a = a * a;
b >>= 1;
}
ans.clearbackzero();
return ans;
}
data gcd(data a, data b) {
if (b > a) return gcd(b, a);
b.clearbackzero();
if (b.is_zero()) {
a.clearbackzero();
return a;
}
a.clearbackzero();
return gcd(b, a % b);
}
}
using namespace Bignum;