Skip to content

Commit e48cdc2

Browse files
committed
support hex addition
1 parent f0cbd7b commit e48cdc2

File tree

3 files changed

+73
-9
lines changed

3 files changed

+73
-9
lines changed

cp-algo/math/bigint.hpp

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace cp_algo::math {
77
enum base_v {
88
x10 = uint64_t(1e18),
9-
x16 = 0
9+
x16 = uint64_t(0)
1010
};
1111
template<base_v base = x10>
1212
struct bigint {
@@ -46,6 +46,13 @@ namespace cp_algo::math {
4646
d_ptr[i] -= o_ptr[i] + carry;
4747
carry = d_ptr[i] >= base;
4848
d_ptr[i] += carry ? uint64_t(base) : 0;
49+
} else if constexpr (base == x16) {
50+
auto sub = o_ptr[i] + carry;
51+
auto new_carry = sub ? (d_ptr[i] < sub) : carry;
52+
d_ptr[i] -= sub;
53+
carry = new_carry;
54+
} else {
55+
static_assert(base == x10 || base == x16, "Unsupported base");
4956
}
5057
}
5158
if (carry) {
@@ -80,11 +87,18 @@ namespace cp_algo::math {
8087
d_ptr[i] += o_ptr[i] + carry;
8188
carry = d_ptr[i] >= base;
8289
d_ptr[i] -= carry ? uint64_t(base) : 0;
90+
} else if constexpr (base == x16) {
91+
auto add = o_ptr[i] + carry;
92+
auto new_carry = add ? (d_ptr[i] >= -add) : carry;
93+
d_ptr[i] += add;
94+
carry = new_carry;
95+
} else {
96+
static_assert(base == x10 || base == x16, "Unsupported base");
8397
}
8498
}
8599
if (carry) {
86100
N = size(digits);
87-
for (; i < N && d_ptr[i] == base - 1; i++) {
101+
for (; i < N && d_ptr[i] == uint64_t(base) - 1; i++) {
88102
d_ptr[i] = 0;
89103
}
90104
if (i < N) {
@@ -104,10 +118,10 @@ namespace cp_algo::math {
104118
size_t len = size(s);
105119
assert(len > 0);
106120
constexpr auto digit_length = base == x10 ? 18 : base == x16 ? 16 : 0;
121+
constexpr auto sub_base = base == x10 ? 10 : base == x16 ? 16 : 0;
107122
size_t num_digits = (len + digit_length - 1) / digit_length;
108123
digits.resize(num_digits);
109124
size_t i = len;
110-
constexpr auto sub_base = base == x10 ? 10 : base == x16 ? 16 : 0;
111125
for (size_t j = 0; j < num_digits - 1; j++) {
112126
std::from_chars(s.data() + i - digit_length, s.data() + i, digits[j], sub_base);
113127
i -= digit_length;
@@ -140,11 +154,28 @@ namespace cp_algo::math {
140154
if (empty(x.digits)) {
141155
return out << '0';
142156
}
143-
if constexpr (base == x10) {
144-
out << x.digits.back();
145-
for (auto d: x.digits | std::views::reverse | std::views::drop(1)) {
146-
out << std::string(18 - size(std::to_string(d)), '0') << d;
157+
constexpr auto digit_length = base == x10 ? 18 : base == x16 ? 16 : 0;
158+
constexpr auto sub_base = base == x10 ? 10 : base == x16 ? 16 : 0;
159+
char buf[20];
160+
auto [ptr, ec] = std::to_chars(buf, buf + sizeof(buf), x.digits.back(), sub_base);
161+
if constexpr (base == x16) {
162+
for (char* p = buf; p != ptr; ++p) {
163+
*p = (char)std::toupper(*p);
164+
}
165+
}
166+
buf[ptr - buf] = 0;
167+
out << buf;
168+
for (auto d: x.digits | std::views::reverse | std::views::drop(1)) {
169+
auto [ptr, ec] = std::to_chars(buf, buf + sizeof(buf), d, sub_base);
170+
if constexpr (base == x16) {
171+
for (char* p = buf; p != ptr; ++p) {
172+
*p = (char)std::toupper(*p);
173+
}
147174
}
175+
auto len = ptr - buf;
176+
out << std::string(digit_length - len, '0');
177+
buf[len] = 0;
178+
out << buf;
148179
}
149180
return out;
150181
}

verify/number_theory/bigint_addition.test.cpp renamed to verify/bigint/addition.test.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// @brief Addition of Big Integers
22
#define PROBLEM "https://judge.yosupo.jp/problem/addition_of_big_integers"
33
#pragma GCC optimize("O3,unroll-loops")
4-
//#pragma GCC target("avx2")
4+
#include <bits/allocator.h>
5+
#pragma GCC target("avx2")
56
#define CP_ALGO_CHECKPOINT
67
#include <iostream>
7-
//#include "blazingio/blazingio.min.hpp"
8+
#include "blazingio/blazingio.min.hpp"
89
#include "cp-algo/math/bigint.hpp"
910
#include "cp-algo/util/checkpoint.hpp"
1011
#include <bits/stdc++.h>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @brief Addition of Hex Big Integers
2+
#define PROBLEM "https://judge.yosupo.jp/problem/addition_of_hex_big_integers"
3+
#pragma GCC optimize("O3,unroll-loops")
4+
#include <bits/allocator.h>
5+
#pragma GCC target("avx2")
6+
#define CP_ALGO_CHECKPOINT
7+
#include <iostream>
8+
#include "blazingio/blazingio.min.hpp"
9+
#include "cp-algo/math/bigint.hpp"
10+
#include "cp-algo/util/checkpoint.hpp"
11+
#include <bits/stdc++.h>
12+
13+
using namespace std;
14+
using namespace cp_algo::math;
15+
16+
void solve() {
17+
bigint<x16> a, b;
18+
cin >> a >> b;
19+
cout << (a += b) << "\n";
20+
}
21+
22+
signed main() {
23+
//freopen("input.txt", "r", stdin);
24+
ios::sync_with_stdio(0);
25+
cin.tie(0);
26+
int t = 1;
27+
cin >> t;
28+
while(t--) {
29+
solve();
30+
}
31+
cp_algo::checkpoint<1>();
32+
}

0 commit comments

Comments
 (0)