QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#705864 | #8340. 3 Sum | nhuang685 | TL | 385ms | 4152kb | C++23 | 9.4kb | 2024-11-03 03:01:37 | 2024-11-03 03:01:39 |
Judging History
answer
/**
* @author n685
* @brief
* @date 2024-11-02 10:54:24
*
*
*/
#include "bits/stdc++.h"
#ifdef LOCAL
#include "dd/debug.h"
#else
#define dbg(...) 42
#define dbg_proj(...) 420
#define dbg_rproj(...) 420420
void nline() {}
void bar() {}
void start_clock() {}
void end_clock() {}
#endif
namespace rs = std::ranges;
namespace rv = std::views;
inline namespace bigint {
// based on https://cp-algorithms.com/algebra/big-integer.html
struct BigInt {
static constexpr int LG = 1;
static constexpr int BASE = []() -> int {
int ans = 1;
for (int i = 0; i < LG; ++i) {
ans *= 10;
}
return ans;
}();
std::vector<int> a;
BigInt() = default;
explicit BigInt(std::integral auto val) {
while (val > 0) {
a.push_back(static_cast<int>(val % BASE));
val /= BASE;
}
}
explicit BigInt(const std::string& s) {
for (int i = static_cast<int>(s.size()) - 1; i >= 0; i -= LG) {
if (i < LG) {
a.push_back(std::stoi(s.substr(0, i + 1)));
} else {
a.push_back(std::stoi(s.substr(i - LG + 1, LG)));
}
}
trim();
}
explicit BigInt(const std::vector<int>& v) : a(v) {}
friend std::istream& operator>>(std::istream& in, BigInt& val) {
std::string s;
in >> s;
val = BigInt{s};
return in;
}
friend std::ostream& operator<<(std::ostream& out, const BigInt& val) {
for (int i : val.a | rv::reverse) {
out << i;
}
return out;
}
void trim() {
while (!a.empty() && a.back() == 0) {
a.pop_back();
}
}
BigInt& operator+=(const BigInt& rhs) {
int carry = 0;
for (int i = 0; i < std::max(std::ssize(a), std::ssize(rhs.a)) || carry > 0; ++i) {
if (i == std::ssize(a)) {
a.push_back(0);
}
a[i] += carry + (i < std::ssize(rhs.a) ? rhs.a[i] : 0);
carry = (a[i] >= BASE) ? 1 : 0;
if (a[i] >= BASE) {
a[i] -= BASE;
}
}
return *this;
}
BigInt& operator-=(const BigInt& rhs) {
int carry = 0;
for (int i = 0; i < std::ssize(rhs.a) || carry > 0; ++i) {
a[i] -= carry + (i < std::ssize(rhs.a) ? rhs.a[i] : 0);
carry = (a[i] < 0) ? 1 : 0;
if (a[i] < 0) {
a[i] += BASE;
}
}
trim();
return *this;
}
BigInt& operator*=(int rhs) {
assert(rhs < BASE);
int carry = 0;
for (int i = 0; i < std::ssize(a) || carry > 0; ++i) {
if (i == std::ssize(a)) {
a.push_back(0);
}
int64_t cur = carry + int64_t{a[i]} * rhs;
a[i] = static_cast<int>(cur % BASE);
carry = static_cast<int>(cur / BASE);
}
return *this;
}
friend BigInt operator*(const BigInt& lhs, const BigInt& rhs) {
BigInt ans;
ans.a.resize(lhs.a.size() + rhs.a.size());
for (int i = 0; i < std::ssize(lhs.a); ++i) {
for (int j = 0, carry = 0; j < std::ssize(rhs.a) || carry > 0; ++j) {
int64_t cur
= ans.a[i + j] + int64_t{lhs.a[i]} * (j < std::ssize(rhs.a) ? rhs.a[j] : 0) + carry;
ans.a[i + j] = static_cast<int>(cur % BASE);
carry = static_cast<int>(cur / BASE);
}
}
ans.trim();
return ans;
}
BigInt& operator*=(const BigInt& rhs) { return *this = *this * rhs; }
int div_mod(int rhs) {
int carry = 0;
for (int i = static_cast<int>(a.size()) - 1; i >= 0; --i) {
int64_t cur = a[i] + int64_t{carry} * BASE;
a[i] = static_cast<int>(cur / rhs);
carry = static_cast<int>(cur % rhs);
}
trim();
return carry;
}
BigInt& operator/=(int rhs) {
div_mod(rhs);
return *this;
}
int operator%(int rhs) {
int carry = 0;
for (int i = static_cast<int>(a.size()) - 1; i >= 0; --i) {
carry = static_cast<int>((a[i] + int64_t{carry} * BASE) % rhs);
}
return carry;
}
bool operator==(const BigInt& rhs) const = default;
bool operator!=(const BigInt& rhs) const = default;
auto operator<=>(const BigInt& rhs) const {
if (a.size() != rhs.a.size()) {
return a.size() <=> rhs.a.size();
}
for (int i = static_cast<int>(a.size()) - 1; i >= 0; --i) {
if (a[i] != rhs.a[i]) {
return a[i] <=> rhs.a[i];
}
}
return std::strong_ordering::equal;
}
};
BigInt operator+(BigInt a, const BigInt& b) { return a += b; }
BigInt operator-(BigInt a, const BigInt& b) { return a -= b; }
BigInt operator*(BigInt a, int b) { return a *= b; }
BigInt operator*(int b, BigInt a) { return a *= b; }
} // namespace bigint
#if defined(LOCAL) && __cplusplus >= 202302L
template <> struct std::formatter<BigInt, char> {
std::formatter<std::string, char> underlying;
constexpr formatter() {
if constexpr (requires { underlying.set_debug_format(); }) {
underlying.set_debug_format();
}
}
template <class ParseContext> constexpr auto parse(ParseContext& ctx) {
return underlying.parse(ctx);
}
template <class FormatContext> auto format(const BigInt& val, FormatContext& ctx) const {
return underlying.format(std::stringstream{} << val, ctx);
}
};
#endif
namespace multihash {
template <class T> constexpr std::pair<T, T> ex_eucl(T a, T b) {
if (a < b) {
auto [x, y] = ex_eucl(b, a);
return {y, x};
}
if (b == 0) {
assert(a == 1);
return {1, 0};
}
auto [x, y] = ex_eucl(b, a % b);
return {y, x - (a / b) * y};
}
template <int NUM> struct MultiHash {
static constexpr int MAX = 1'000'000'007;
// static inline const std::array<int, NUM> mods = []() {
// std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
// std::uniform_int_distribution<int> rnd(10000, MAX);
// std::array<int, NUM> ans{};
// for (int& v : ans) {
// v = rnd(rng);
// }
// return ans;
// }();
static inline const std::array<int, NUM> mods{1'000'000'007, 1'000'000'009, 998'244'353};
template <class T> static constexpr T normalize(std::integral auto val, T mod) {
using U = decltype(mod + val);
U uval = static_cast<U>(val);
U umd = static_cast<U>(mod);
if (uval <= -umd || umd <= uval) {
uval %= umd;
}
if (val < 0) {
uval += umd;
}
return static_cast<T>(uval);
}
std::array<int, NUM> vals{};
MultiHash() = default;
explicit MultiHash(std::integral auto val) {
for (int i = 0; i < NUM; ++i) {
vals[i] = normalize(val, mods[i]);
}
}
MultiHash& operator+=(const MultiHash& rhs) {
for (int i = 0; i < NUM; ++i) {
vals[i] += rhs.vals[i];
if (vals[i] >= mods[i]) {
vals[i] -= mods[i];
}
}
return *this;
}
friend MultiHash operator+(MultiHash lhs, const MultiHash& rhs) { return lhs += rhs; }
MultiHash& operator-=(const MultiHash& rhs) {
for (int i = 0; i < NUM; ++i) {
vals[i] -= rhs.vals[i];
if (vals[i] < 0) {
vals[i] += mods[i];
}
}
return *this;
}
MultiHash operator-() const {
MultiHash ans;
for (int i = 0; i < NUM; ++i) {
ans.vals[i] = normalize(-vals[i], mods[i]);
}
return ans;
}
friend MultiHash operator-(MultiHash lhs, const MultiHash& rhs) { return lhs -= rhs; }
MultiHash& operator*=(const MultiHash& rhs) {
for (int i = 0; i < NUM; ++i) {
vals[i] = static_cast<int>(int64_t{vals[i]} * rhs.vals[i] % mods[i]);
}
return *this;
}
friend MultiHash operator*(MultiHash lhs, const MultiHash& rhs) { return lhs *= rhs; }
MultiHash binpow(std::integral auto b) const {
MultiHash res{1}, a = *this;
while (b > 0) {
if (b % 2 == 1) {
res *= a;
}
a *= a;
b /= 2;
}
return res;
}
MultiHash inv() const {
MultiHash ans;
for (int i = 0; i < NUM; ++i) {
ans.vals[i] = normalize(ex_eucl<int64_t>(vals[i], mods[i]).first);
}
return ans;
}
bool operator==(const MultiHash& rhs) const = default;
auto operator<=>(const MultiHash& rhs) const = default;
};
} // namespace multihash
using Hash = multihash::MultiHash<3>;
constexpr int MX = 10;
int main() {
#ifndef LOCAL
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
#endif
const std::array<Hash, MX + 1> digits = []() {
std::array<Hash, MX + 1> ans{};
for (int i = 0; i <= 10; ++i) {
ans[i] = Hash{i};
}
return ans;
}();
int n, k;
std::cin >> n >> k;
BigInt m{std::vector(k, 9)};
Hash hm;
for (int j : m.a | rv::reverse) {
hm = digits[10] * hm + Hash{j};
}
std::vector<Hash> a(n);
for (int i = 0; i < n; ++i) {
BigInt v;
std::cin >> v;
while (v > m) {
BigInt nv;
for (int j = 0; j < std::ssize(v.a); j += k) {
nv += BigInt{
std::vector(v.a.begin() + j, v.a.begin() + std::min(j + k, static_cast<int>(v.a.size())))
};
}
v = nv;
}
if (v == m) {
v = BigInt{0};
}
for (int j : v.a | rv::reverse) {
a[i] = digits[10] * a[i] + Hash{j};
}
}
std::map<Hash, int> freq;
int ans = 0;
Hash hm2 = digits[2] * hm;
for (int i = 0; i < n; ++i) {
++freq[a[i]];
for (int j = i; j < n; ++j) {
Hash sum = a[i] + a[j];
if (freq.contains(-sum)) {
ans += freq[-sum];
}
if (freq.contains(hm - sum)) {
ans += freq[hm - sum];
}
if (freq.contains(hm2 - sum)) {
ans += freq[hm2 - sum];
}
}
}
std::cout << ans << '\n';
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 3896kb
input:
4 1 0 1 10 17
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: 0
Accepted
time: 34ms
memory: 3664kb
input:
500 859 7118711592236878297922359501613604144948355616986970837340677671376753603836852811886591300370143151943368529129749813118476151865844255212534355441611481420938483178075143062691345257288242460282715389758789648541099090735875617822348551942134616963557723055980260082230902505269975518146286...
output:
0
result:
ok 1 number(s): "0"
Test #3:
score: 0
Accepted
time: 385ms
memory: 4152kb
input:
500 17336 11871159223687829792235950161360414494835561698697083734067767137675360383685281188659130037014315194336852912974981311847615186584425521253435544161148142093848317807514306269134525728824246028271538975878964854109909073587561782234855194213461696355772305598026008223090250526997551814628...
output:
0
result:
ok 1 number(s): "0"
Test #4:
score: -100
Time Limit Exceeded
input:
500 1 751324443898124078584847834484321089092662321556147445230263526014359393841194947303407593948729802551881289193716611867931891257925091769456350249725997883453296895094445731130479434019358742162771547784250401546380268386074363779242500860317042151185119666027858022664683818314351285215150806...
output:
2327631