problemscpp
A collection of my answers to algorithm problems in c++.
templates.cpp
浏览该文件的文档.
1#include "templates.h"
2#include <cstring>
3#include <numeric>
4#include <sstream>
5#include <unordered_set>
6
7using namespace std;
8
9void TrieNode::insert(const string &str) {
10 if(this->nexts[str[0] - 'a'] == nullptr) {
11 this->nexts[str[0] - 'a'] = new TrieNode(str[0]);
12 }
13 if(str.length() == 1) {
14 this->nexts[str[0] - 'a']->end_of_word = true;
15 this->nexts[str[0] - 'a']->count++;
16 } else {
17 this->nexts[str[0] - 'a']->insert(str.substr(1));
18 }
19}
20
22 for(const auto *next: this->nexts) {
23 delete next;
24 }
25}
26
27unsigned long BigInt::get_size() const { return vec.size(); }
28
29unsigned short BigInt::operator[](unsigned long i) const { return vec[i]; }
30
31BigInt::BigInt(const vector<unsigned short> &vec, bool positive)
32 : positive(positive) {
33 int end_i = vec.size() - 1;
34 while(end_i >= 0 && vec[end_i] == 0) {
35 end_i--;
36 }
37 this->vec = vector<unsigned short>();
38 for(int i = 0; i <= end_i; i++) {
39 this->vec.push_back(vec[i]);
40 }
41 if(this->vec.empty()) {
42 this->vec.push_back(0);
43 }
44}
45
47 if(n < 0) {
48 positive = false;
49 n = -n;
50 }
51 vec = vector<unsigned short>();
52 stringstream ss;
53 ss << n;
54 char ch;
55 while(ss >> ch) {
56 vec.push_back(ch - '0');
57 }
58}
59
61 if(n < 0) {
62 positive = false;
63 n = -n;
64 }
65 vec = vector<unsigned short>();
66 stringstream ss;
67 ss << n;
68 char ch;
69 while(ss >> ch) {
70 vec.push_back(ch - '0');
71 }
72}
73
75 if(n < 0) {
76 positive = false;
77 n = -n;
78 }
79 vec = vector<unsigned short>();
80 stringstream ss;
81 ss << n;
82 char ch;
83 while(ss >> ch) {
84 vec.push_back(ch - '0');
85 }
86}
87
88BigInt::BigInt(long long int n) {
89 if(n < 0) {
90 positive = false;
91 n = -n;
92 }
93 vec = vector<unsigned short>();
94 do {
95 vec.push_back(n % 10);
96 n /= 10;
97 } while(n != 0);
98}
99
100BigInt::BigInt(unsigned short n) {
101 vec = vector<unsigned short>();
102 do {
103 vec.push_back(n % 10);
104 n /= 10;
105 } while(n != 0);
106}
107
108BigInt::BigInt(unsigned int n) {
109 vec = vector<unsigned short>();
110 do {
111 vec.push_back(n % 10);
112 n /= 10;
113 } while(n != 0);
114}
115
116BigInt::BigInt(unsigned long n) {
117 vec = vector<unsigned short>();
118 do {
119 vec.push_back(n % 10);
120 n /= 10;
121 } while(n != 0);
122}
123
124BigInt::BigInt(unsigned long long int n) {
125 vec = vector<unsigned short>();
126 do {
127 vec.push_back(n % 10);
128 n /= 10;
129 } while(n != 0);
130}
131
132BigInt::BigInt(const string &str) {
133 int start_i = str.length() - 1;
134 while(start_i >= 0 && isdigit(str[start_i]) != 0) {
135 vec.push_back(str[start_i] - '0');
136 start_i--;
137 }
138 if(str[0] == '-') {
139 positive = false;
140 }
141}
142
143BigInt::BigInt(const char *str) {
144 int start_i = strlen(str) - 1;
145 while(start_i >= 0 && isdigit(str[start_i]) != 0) {
146 vec.push_back(str[start_i] - '0');
147 start_i--;
148 }
149 if(str[0] == '-') {
150 positive = false;
151 }
152}
153
155 int end_i = bi.vec.size() - 1;
156 while(end_i >= 0 && bi.vec[end_i] == 0) {
157 end_i--;
158 }
159 this->vec = vector<unsigned short>();
160 for(int i = 0; i <= end_i; i++) {
161 this->vec.push_back(bi.vec[i]);
162 }
163 if(this->vec.empty()) {
164 this->vec.push_back(0);
165 }
166 this->positive = bi.positive;
167}
168
170 if(this->positive && !bi.positive) {
171 return *this - -bi;
172 }
173 if(!this->positive && bi.positive) {
174 return bi - -*this;
175 }
176 vector<unsigned short> v;
177 unsigned short carry = 0;
178 for(long long i = 0; i < max(this->get_size(), bi.get_size()) || carry != 0; i++) {
179 const unsigned short this_num = i < this->get_size() ? (*this)[i] : 0;
180 const unsigned short bi_num = i < bi.get_size() ? bi[i] : 0;
181 unsigned short sum = this_num + bi_num;
182 sum += carry;
183 carry = sum / 10;
184 sum %= 10;
185 v.push_back(sum);
186 }
187 auto ret = BigInt(v, this->positive);
188 return ret;
189}
190
192 if(this->positive != bi.positive) {
193 return *this + -bi;
194 }
195 if(!this->positive) {
196 return -bi - -*this;
197 }
198 if(*this < bi) {
199 return -(bi - *this);
200 }
201 vector<unsigned short> v;
202 unsigned short borrow = 0;
203 for(long long i = 0; i < max(this->get_size(), bi.get_size()); i++) {
204 short this_num = i < this->get_size() ? (*this)[i] : 0;
205 const short bi_num = i < bi.get_size() ? bi[i] : 0;
206 this_num -= borrow;
207 short diff = this_num - bi_num;
208 borrow = 0;
209 while(diff < 0) {
210 borrow++;
211 diff += 10;
212 }
213 v.push_back(diff);
214 }
215 auto ret = BigInt(v, true);
216 return ret;
217}
218
219vector<unsigned short> BigInt::operator*(const unsigned short n) const {
220 vector<unsigned short> res;
221 unsigned short c = 0;
222 for(const auto v: this->vec) {
223 unsigned short num = n * v + c;
224 c = num / 10;
225 num %= 10;
226 res.emplace_back(num);
227 }
228 while(c > 0) {
229 res.emplace_back(c % 10);
230 c /= 10;
231 }
232 return res;
233}
234
236 unsigned max_len = 0;
237 vector<vector<unsigned short>> vecs(bi.vec.size());
238 for(int i = 0; i < bi.vec.size(); i++) {
239 vector<unsigned short> vi(i, 0);
240 vector<unsigned short> ai = *this * bi.vec[i];
241 vi.insert(vi.end(), ai.begin(), ai.end());
242 vecs[i] = vi;
243 max_len = max(max_len, static_cast<unsigned>(vi.size()));
244 }
245 vector<unsigned short> ans;
246 unsigned short c = 0;
247 for(int i = 0; i < max_len; i++) {
248 unsigned int v = 0;
249 for(int j = 0; j < vecs.size(); j++) {
250 v += i < vecs[j].size() ? vecs[j][i] : 0;
251 }
252 v += c;
253 c = v / 10;
254 v %= 10;
255 ans.emplace_back(v);
256 }
257 while(c > 0) {
258 ans.emplace_back(c % 10);
259 c /= 10;
260 }
261 return BigInt(ans, (*this).positive == bi.positive);
262}
263
264BigInt BigInt::operator/(const BigInt & /*bi*/) const { return *this; }
265
266BigInt BigInt::operator%(const BigInt & /*bi*/) const { return *this; }
267
268bool BigInt::operator>(const BigInt &bi) const {
269 if(this->positive != bi.positive) {
270 return this->positive;
271 }
272 if(!this->positive && !bi.positive) {
273 return -*this < -bi;
274 }
275 if(this->get_size() != bi.get_size()) {
276 return this->get_size() > bi.get_size();
277 }
278
279 for(int i = get_size() - 1; i >= 0; --i) {
280 if((*this)[i] > bi[i]) {
281 return true;
282 }
283 if((*this)[i] < bi[i]) {
284 return false;
285 }
286 if((*this)[i] < bi[i]) {
287 return false;
288 }
289 }
290 return false;
291}
292
293bool BigInt::operator<(const BigInt &bi) const {
294 if(this->positive != bi.positive) {
295 return !this->positive;
296 }
297 if(!this->positive && !bi.positive) {
298 return -*this > -bi;
299 }
300 if(this->get_size() != bi.get_size()) {
301 return this->get_size() < bi.get_size();
302 }
303 return !(*this >= bi);
304}
305
306bool BigInt::operator==(const BigInt &bi) const {
307 if(this->positive == bi.positive) {
308 return this->vec == bi.vec;
309 }
310 return false;
311}
312
313bool BigInt::operator!=(const BigInt &bi) const {
314 if(this->positive == bi.positive) {
315 return this->vec != bi.vec;
316 }
317 return true;
318}
319
320bool BigInt::operator>=(const BigInt &bi) const { return *this == bi || *this > bi; }
321
322bool BigInt::operator<=(const BigInt &bi) const { return *this == bi || *this < bi; }
323
325 *this = *this + bi;
326 return *this;
327}
328
330 *this = *this - bi;
331 return *this;
332}
333
335 *this = *this * bi;
336 return *this;
337}
338
340 *this = *this / bi;
341 return *this;
342}
343
345 *this = *this % bi;
346 return *this;
347}
348
349ostream &operator<<(ostream &os, const BigInt &bi) {
350 if(!bi.positive) {
351 os << '-';
352 }
353 for(auto it = bi.vec.rbegin(); it != bi.vec.rend(); ++it) {
354 os << *it;
355 }
356 return os;
357}
358
359istream &operator>>(istream &is, const BigInt & /*bi*/) { return is; }
360
361BigInt BigInt::operator-() const { return BigInt(this->vec, !this->positive); }
362
364 *this += 1;
365 return *this;
366}
367
369 *this -= 1;
370 return *this;
371}
372
374 auto ret = BigInt(*this);
375 *this += 1;
376 return ret;
377}
378
380 auto ret = BigInt(*this);
381 *this -= 1;
382 return ret;
383}
385 vec = vector<unsigned short>();
386 positive = true;
387}
388
389bool Fraction::is_positive() const { return positive; }
390
391unsigned long long Fraction::get_numerator() const { return numerator; }
392
393unsigned long long Fraction::get_denominator() const { return denominator; }
394
396 const unsigned long long factor = gcd(numerator, denominator);
397 numerator /= factor;
398 denominator /= factor;
399}
400
401Fraction::Fraction(bool positive, long long numerator, long long denominator) {
402 if(numerator < 0) {
404 }
405 if(denominator < 0) {
407 }
408 this->positive = positive;
409 this->numerator = abs(numerator);
410 this->denominator = abs(denominator);
411 this->simplify();
412}
413
415 long long numerator1 = this->numerator * f.denominator;
416 long long numerator2 = this->denominator * f.numerator;
417 if(!this->positive) {
418 numerator1 = -numerator1;
419 }
420 if(!f.positive) {
421 numerator2 = -numerator2;
422 }
423 return {true, numerator1 + numerator2, static_cast<long long>(this->denominator * f.denominator)};
424}
425
427 long long numerator1 = this->numerator * f.denominator;
428 long long numerator2 = this->denominator * f.numerator;
429 if(!this->positive) {
430 numerator1 = -numerator1;
431 }
432 if(!f.positive) {
433 numerator2 = -numerator2;
434 }
435 return {true, numerator1 - numerator2, static_cast<long long>(this->denominator * f.denominator)};
436}
437
439 long long numerator1 = this->numerator;
440 long long numerator2 = f.numerator;
441 if(!this->positive) {
442 numerator1 = -numerator1;
443 }
444 if(!f.positive) {
445 numerator2 = -numerator2;
446 }
447 return {true, numerator1 * numerator2, static_cast<long long>(this->denominator * f.denominator)};
448}
449
450Fraction Fraction::operator/(const Fraction &f) const { return *this * Fraction(f.positive, f.denominator, f.numerator); }
451
452ostream &operator<<(ostream &os, const Fraction &frac) {
453 if(frac.denominator == 0) {
454 os << "Inf";
455 return os;
456 }
457 if(frac.numerator == 0) {
458 os << 0;
459 return os;
460 }
461 if(!frac.positive) {
462 os << "(-";
463 }
464 if(frac.numerator % frac.denominator == 0) {
465 os << frac.numerator / frac.denominator;
466 } else {
467 if(frac.numerator / frac.denominator != 0) {
468 os << frac.numerator / frac.denominator << ' ';
469 }
470 os << frac.numerator % frac.denominator << '/' << frac.denominator;
471 }
472 if(!frac.positive) {
473 os << ")";
474 }
475 return os;
476}
477
479 this->parent = vector<int>(n);
480 this->rank = vector<int>(n);
481 this->size = vector<int>(n);
482 for(int i = 0; i < n; i++) {
483 this->parent[i] = i;
484 this->rank[i] = 0;
485 size[i] = 1;
486 }
487}
488
489int UnionFind::find(int x) {
490 if(parent[x] != x) {
491 parent[x] = find(parent[x]);
492 }
493 return parent[x];
494}
495
496void UnionFind::unite(int x, int y) {
497 x = find(x);
498 y = find(y);
499 if(x == y) {
500 return;
501 }
502 if(rank[x] < rank[y]) {
503 parent[x] = y;
504 size[y] += size[x];
505 } else {
506 parent[y] = x;
507 size[x] += size[y];
508 if(rank[x] == rank[y]) {
509 rank[x]++;
510 }
511 }
512}
513
514bool UnionFind::same(int x, int y) { return find(x) == find(y); }
515
516int UnionFind::get_size(int x) { return size[find(x)]; }
517
519 unordered_set<int> us;
520 for(int i = 0; i < size.size(); i++) {
521 us.insert(find(i));
522 }
523 return us.size();
524}
525
526Matrix::Matrix(int n) { mat = vector<vector<int>>(n, vector<int>(n, 0)); }
527
529 mat = vector<vector<int>>(m.mat.size(), vector<int>(m.mat.size(), 0));
530 for(int i = 0; i < m.mat.size(); i++) {
531 for(int j = 0; j < m.mat.size(); j++) {
532 mat[i][j] = m.mat[i][j];
533 }
534 }
535}
536
538 Matrix ret(mat.size());
539 for(int i = 0; i < mat.size(); i++) {
540 for(int j = 0; j < mat.size(); j++) {
541 for(int k = 0; k < mat.size(); k++) {
542 ret.mat[i][j] += mat[i][k] * m.mat[k][j];
543 }
544 }
545 }
546 return ret;
547}
548
549vector<int> &Matrix::operator[](int i) {
550 return mat[i];
551}
552
553const vector<int> &Matrix::operator[](int i) const {
554 return mat[i];
555}
556
558 Matrix ret(n);
559 for(int i = 0; i < n; i++) {
560 ret.mat[i][i] = 1;
561 }
562 return ret;
563}
ostream & operator<<(ostream &os, const BigInt &bi)
Definition: templates.cpp:349
istream & operator>>(istream &is, const BigInt &)
Definition: templates.cpp:359
int vec[100010]
Definition: pat.cpp:5095
array< TrieNode *, 26 > nexts
Definition: templates.h:11
void insert(const string &str)
Definition: templates.cpp:9
TrieNode(char ch)
Definition: templates.h:15
高精度整数
Definition: templates.h:23
BigInt & operator++()
Definition: templates.cpp:363
bool operator>(const BigInt &bi) const
Definition: templates.cpp:268
BigInt operator+(const BigInt &bi) const
Definition: templates.cpp:169
vector< unsigned short > operator*(unsigned short n) const
Definition: templates.cpp:219
unsigned short operator[](unsigned long) const
Definition: templates.cpp:29
unsigned long get_size() const
Definition: templates.cpp:27
BigInt & operator*=(const BigInt &bi)
Definition: templates.cpp:334
bool operator<(const BigInt &bi) const
Definition: templates.cpp:293
BigInt & operator-=(const BigInt &bi)
Definition: templates.cpp:329
bool operator!=(const BigInt &bi) const
Definition: templates.cpp:313
BigInt operator-() const
Definition: templates.cpp:361
bool positive
Definition: templates.h:25
BigInt operator/(const BigInt &bi) const
Definition: templates.cpp:264
BigInt operator%(const BigInt &bi) const
Definition: templates.cpp:266
bool operator<=(const BigInt &bi) const
Definition: templates.cpp:322
bool operator>=(const BigInt &bi) const
Definition: templates.cpp:320
vector< unsigned short > vec
Definition: templates.h:26
BigInt & operator/=(const BigInt &bi)
Definition: templates.cpp:339
BigInt & operator+=(const BigInt &bi)
Definition: templates.cpp:324
BigInt & operator--()
Definition: templates.cpp:368
bool operator==(const BigInt &bi) const
Definition: templates.cpp:306
BigInt & operator%=(const BigInt &bi)
Definition: templates.cpp:344
分数
Definition: templates.h:71
bool is_positive() const
Definition: templates.cpp:389
Fraction operator+(const Fraction &f) const
Definition: templates.cpp:414
Fraction(bool positive, long long numerator, long long denominator)
Definition: templates.cpp:401
Fraction operator-(const Fraction &f) const
Definition: templates.cpp:426
unsigned long long get_denominator() const
Definition: templates.cpp:393
unsigned long long get_numerator() const
Definition: templates.cpp:391
unsigned long long denominator
分母
Definition: templates.h:75
void simplify()
Definition: templates.cpp:395
bool positive
正负
Definition: templates.h:73
Fraction operator/(const Fraction &f) const
Definition: templates.cpp:450
unsigned long long numerator
分子
Definition: templates.h:74
Fraction operator*(const Fraction &f) const
Definition: templates.cpp:438
vector< int > size
Definition: templates.h:95
void unite(int x, int y)
Definition: templates.cpp:496
vector< int > rank
Definition: templates.h:94
int get_size(int x)
Definition: templates.cpp:516
vector< int > parent
Definition: templates.h:93
bool same(int x, int y)
Definition: templates.cpp:514
int find(int x)
Definition: templates.cpp:489
UnionFind(int n)
Definition: templates.cpp:478
unsigned count()
Definition: templates.cpp:518
矩阵
Definition: templates.h:107
vector< vector< int > > mat
Definition: templates.h:109
Matrix operator*(const Matrix &m) const
Definition: templates.cpp:537
vector< int > & operator[](int i)
Definition: templates.cpp:549
static Matrix identity(int n)
Definition: templates.cpp:557
Matrix(int n)
Definition: templates.cpp:526