結果
問題 |
No.3118 Increment or Multiply
|
ユーザー |
|
提出日時 | 2025-04-20 13:16:46 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,315 bytes |
コンパイル時間 | 2,201 ms |
コンパイル使用メモリ | 195,172 KB |
実行使用メモリ | 7,848 KB |
最終ジャッジ日時 | 2025-04-20 13:16:50 |
合計ジャッジ時間 | 3,998 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 5 WA * 30 |
ソースコード
#include <bits/stdc++.h> using namespace std; using int64 = long long; using i128 = __int128_t; const int64 MOD = 998244353; const int64 INV2 = 499122177; // 2^{-1} mod MOD // a*b mod MOD (a,b < MOD) inline int64 mul_mod(i128 a, i128 b) { return (int64)((a * b) % MOD); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while (T--) { uint64_t N, A; // N, A ≤ 1e18 cin >> N >> A; int64 Nmod = N % MOD; int64 answer = 0; if (A == 1) { // N*(N-1)/2 mod MOD answer = mul_mod(Nmod, (Nmod + MOD - 1) % MOD); answer = mul_mod(answer, INV2); cout << answer << '\n'; continue; } uint64_t M = N / A; // floor(N/A) uint64_t len_big = N - M; // 区間 (M, N] // 三角数パート int64 lenb_mod = len_big % MOD; answer = mul_mod(lenb_mod, (lenb_mod + MOD - 1) % MOD); answer = mul_mod(answer, INV2); // len*(len-1)/2 // ループで「掛け算→境界を超える直前の K 範囲」を処理 uint64_t cur_high = M; int64 Apow_mod = A % MOD; // A^t (t = 1 から始める) int t = 1; while (cur_high) { uint64_t next_high = cur_high / A; // ⌊cur/A⌋ uint64_t len = cur_high - next_high; // 区間長 uint64_t low = next_high + 1; uint64_t high = cur_high; // ΣK = (low + high) * len / 2 (mod 計算) int64 sumK_mod = mul_mod( ( (low % MOD) + (high % MOD) ) % MOD, (len % MOD) ); sumK_mod = mul_mod(sumK_mod, INV2); // ① +1,+1,… 部:len * t answer = (answer + mul_mod(len % MOD, t % MOD)) % MOD; // ② N を足す部:N * len answer = (answer + mul_mod(Nmod, len % MOD)) % MOD; // ③ 掛け算側:-A^t * ΣK answer = (answer - mul_mod(Apow_mod, sumK_mod) + MOD) % MOD; // 次の階層へ cur_high = next_high; t++; Apow_mod = mul_mod(Apow_mod, A % MOD); // A^t mod MOD } cout << answer << '\n'; } return 0; }