結果
| 問題 | No.3548 SigMax Digits (Construction ver.) |
| コンテスト | |
| ユーザー |
yamate11
|
| 提出日時 | 2026-05-22 23:07:35 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 44 ms / 2,000 ms |
| コード長 | 5,398 bytes |
| 記録 | |
| コンパイル時間 | 2,478 ms |
| コンパイル使用メモリ | 338,396 KB |
| 実行使用メモリ | 6,400 KB |
| 最終ジャッジ日時 | 2026-05-22 23:07:43 |
| 合計ジャッジ時間 | 5,639 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge3_1 |
| 純コード判定待ち |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 7 |
ソースコード
#include <bits/stdc++.h>
#include <cassert>
using namespace std;
using ll = long long int;
using u64 = unsigned long long;
using pll = pair<ll, ll>;
// #include <atcoder/all>
// using namespace atcoder;
#define REP(i, a, b) for (ll i = (a); i < (b); i++)
#define REPrev(i, a, b) for (ll i = (a); i >= (b); i--)
#define ALL(coll) (coll).begin(), (coll).end()
#define SIZE(v) ((ll)((v).size()))
#define REPOUT(i, a, b, exp, sep) REP(i, (a), (b)) cout << (exp) << (i + 1 == (b) ? "" : (sep)); cout << "\n"
// @@ !! LIM(digit f:intDiv)
// ---- inserted library file digit.cc
// published at https://github.com/yamate11/compprog-clib/blob/master/digit.cc
struct digit_util {
const ll base;
const vector<ll> _pow;
static vector<ll> _make_pow(ll b) {
vector<ll> ret;
ll t = 1;
while (true) {
ret.push_back(t);
if (__builtin_smulll_overflow(t, b, &t)) break;
}
return ret;
};
digit_util(ll base_ = 10) : base(base_), _pow(_make_pow(base_)) {}
ll pow_size() const { return _pow.size(); }
ll pow(ll i) const {
if (i < 0 or ssize(_pow) <= i) return -1;
return _pow[i];
}
ll width(ll x) const {
if (x < 0) return -1;
if (base == 2) return bit_width((unsigned long long)x);
if (x == 0) return 0;
ll ret = 0;
for (; x != 0; x /= base) ret++;
return ret;
}
ll nd_min(ll i) const { return i < 0 ? -1 : i == 0 ? 0 : pow(i - 1); }
ll nd_max(ll i) const { return i < 0 ? -1 : i == 0 ? 0 : nd_min(i + 1) - 1; }
ll floor(ll x) const { return (x < 0) ? -1 : x == 0 ? 0 : _pow[width(x) - 1]; }
ll ceil(ll x) const {
if (x < 0) return -1;
if (x == 0) return 0;
ll p = _pow[width(x) - 1];
return (x == p) ? p : (p * base);
}
ll log(ll x) const { return (x <= 0) ? -1 : width(x) - 1; }
ll d_at(ll x, ll i) const {
if (x < 0) return -1;
if (x == 0) return 0;
if (i < 0) i += width(x);
return (x / pow(i)) % base;
}
ll d_sub(ll x, ll pos, ll len) const {
if (x < 0) return -1;
if (x == 0) return 0;
ll w = width(x);
if (pos < 0) pos += w;
if (len < 0) { len = -len; pos = pos - len + 1; }
if (pos < 0) { len += pos; pos = 0; }
if (pos + len > w) len = w - pos;
return (x % pow(pos + len)) / pow(pos);
}
vector<ll> to_vector(ll x) const {
if (x < 0) return vector<ll>{};
if (x == 0) return vector<ll>{0};
vector<ll> ret;
ret.reserve(width(x));
for ( ; x != 0; x /= base) { ret.push_back(x % base); }
return ret;
}
string to_string(ll x, bool upcase = false) const {
if (x < 0) return string();
if (x == 0) return string("0");
char ten = upcase ? 'A' : 'a';
ll w = width(x);
string ret(w, ' ');
for (ll i = w - 1; x != 0; x /= base, i--) {
ll y = x % base;
ret[i] = y < 10 ? '0' + y : ten + (y - 10);
}
return ret;
}
ll from_vector(const vector<ll>& vec) const {
ll ret = 0;
for (ll i = 0; i < ssize(vec); i++) ret += vec[i] * pow(i);
return ret;
}
static ll _get_digit_char(char c) {
if ('0' <= c and c <= '9') return c - '0';
else if ('a' <= c and c <= 'z') return c - 'a' + 10;
else if ('A' <= c and c <= 'Z') return c - 'A' + 10;
else throw runtime_error("_get_digit_char: unknown letter");
}
ll from_string(string s) const {
ll ret = 0;
for (ll i = 0; i < ssize(s); i++) ret += _get_digit_char(s[i]) * pow(ssize(s) - 1 - i);
return ret;
}
};
// ---- end digit.cc
// ---- inserted function f:intDiv from util.cc
// imod, divFloor, divCeil
// imod(x, y) : remainder of x for y
// for y > 0:
// imod(x, y) = r where x = dy + r, 0 <= r < y
// imod(x, -y) = r where x = dy + r, 0 >= r > y
// Thus, imod( 10, 7) = 3
// imod(-10, 7) = 4
// imod( 10, -7) = -4
// imod(-10, -7) = -3
ll imod(ll x, ll y) {
ll v = x % y;
if ((x >= 0) == (y >= 0)) return v;
else return v == 0 ? 0 : v + y;
}
// Integer Division; regardless pos/neg
ll divFloor(ll x, ll y) {
if (x > 0) {
if (y > 0) return x / y;
else return (x - y - 1) / y;
}else {
if (y > 0) return (x - y + 1) / y;
else return x / y;
}
}
ll divCeil(ll x, ll y) {
if (x > 0) {
if (y > 0) return (x + y - 1) / y;
else return x / y;
}else {
if (y > 0) return x / y;
else return (x + y + 1) / y;
}
}
// Just a note. For d \in Z and t \in R,
// d < t <=> d < ceil(t), d <= t <=> d <= floor(t),
// d > t <=> d > floor(t), d >= t <=> d >= ceil(t).
// ---- end f:intDiv
// @@ !! LIM -- end mark --
int main(/* int argc, char *argv[] */) {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout << setprecision(20);
digit_util du(10);
auto f = [&](ll x) -> ll {
auto v = du.to_vector(x);
return *ranges::max_element(v);
};
auto solve = [&]() -> pll {
ll N; cin >> N;
if (N <= 100) {
REP(l, 1, 100) REP(r, 1, 100) {
ll s = 0;
REP(i, l, r + 1) s += f(i);
if (s == N) return pll(l, r);
}
assert(0);
}
vector<ll> v(18, 8);
v[0] = 9;
ll base = du.from_vector(v);
ll a = divCeil(N, 9);
ll b = a * 9 - N;
if (b == 0) return pll(base, base + a - 1);
return pll(base - b, base + a - 1 - b);
};
ll T; cin >> T;
REP(t, 0, T) {
auto [a, b] = solve();
cout << a << " " << b << "\n";
}
return 0;
}
yamate11