結果
| 問題 | No.3505 Sum of Prod of Root |
| コンテスト | |
| ユーザー |
sient
|
| 提出日時 | 2026-04-19 00:58:55 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 484 ms / 2,000 ms |
| コード長 | 2,929 bytes |
| 記録 | |
| コンパイル時間 | 3,511 ms |
| コンパイル使用メモリ | 340,664 KB |
| 実行使用メモリ | 19,584 KB |
| 最終ジャッジ日時 | 2026-04-19 00:59:24 |
| 合計ジャッジ時間 | 11,009 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 13 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
using u128 = __uint128_t;
static const long long MOD = 998244353;
long long mod_pow(long long a, long long e) {
long long r = 1 % MOD;
while (e > 0) {
if (e & 1) r = (long long)((__int128)r * a % MOD);
a = (long long)((__int128)a * a % MOD);
e >>= 1;
}
return r;
}
long long mod_inv(long long a) {
return mod_pow(a, MOD - 2);
}
const long long INV2 = mod_inv(2);
const long long INV6 = mod_inv(6);
const long long INV30 = mod_inv(30);
long long sum_arith(ull x) {
if (x == 0) return 0;
u128 a = x, b = x + 1;
if ((a & 1) == 0) a >>= 1;
else b >>= 1;
return (long long)((a * b) % MOD);
}
long long prefix_T(ull M) {
if (M == 0) return 0;
ull s = sqrt((long double)M);
while ((u128)(s + 1) * (s + 1) <= M) ++s;
while ((u128)s * s > M) --s;
ull m = s - 1;
long long n = m % MOD;
long long n1 = (n + 1) % MOD;
long long two_n1 = (2 * n + 1) % MOD;
long long poly = ((3LL * n % MOD * n) % MOD + 3LL * n - 1 + MOD) % MOD;
long long S1 = (long long)((__int128)n * n1 % MOD * INV2 % MOD);
long long S2 = (long long)((__int128)n * n1 % MOD * two_n1 % MOD * INV6 % MOD);
long long S3 = (long long)((__int128)S1 * S1 % MOD);
long long S4 = (long long)((__int128)n * n1 % MOD * two_n1 % MOD * poly % MOD * INV30 % MOD);
long long full_blocks = (2LL * S4 + 3LL * S3 + S2) % MOD;
ull sq = s * s;
long long tail = (sum_arith(M) - sum_arith(sq - 1) + MOD) % MOD;
long long tail_part = (long long)((__int128)(s % MOD) * tail % MOD);
return (full_blocks + tail_part) % MOD;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ull N;
cin >> N;
vector<pair<ull, long long>> events;
events.reserve(1100000);
for (ull a = 2;; ++a) {
u128 p = (u128)a * a * a;
if (p > N) break;
long long ratio = (long long)((__int128)(a % MOD) * mod_inv((a - 1) % MOD) % MOD);
while (p <= N) {
events.push_back({(ull)p, ratio});
p *= a;
}
}
sort(events.begin(), events.end(), [](const auto& x, const auto& y) {
return x.first < y.first;
});
ull prev = 1;
long long coeff = 1;
long long ans = 0;
auto add_interval = [&](ull L, ull R) {
if (L > R) return;
long long block = (prefix_T(R) - prefix_T(L - 1) + MOD) % MOD;
ans = (ans + (long long)((__int128)coeff * block % MOD)) % MOD;
};
size_t i = 0;
while (i < events.size()) {
ull v = events[i].first;
add_interval(prev, v - 1);
while (i < events.size() && events[i].first == v) {
coeff = (long long)((__int128)coeff * events[i].second % MOD);
++i;
}
prev = v;
}
add_interval(prev, N);
cout << ans % MOD << '\n';
return 0;
}
sient