結果

問題 No.3607 Sum of Powers of GCDs
コンテスト
ユーザー 👑 loop0919
提出日時 2026-04-12 11:30:55
言語 C++23
(gcc 15.2.0 + boost 1.90.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 442 ms / 2,500 ms
+ 924µs
コード長 1,799 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,618 ms
コンパイル使用メモリ 342,932 KB
実行使用メモリ 97,472 KB
最終ジャッジ日時 2026-07-31 20:50:20
合計ジャッジ時間 6,976 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 11
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;

using ll = long long;
using mint = atcoder::modint998244353;

static constexpr int LIM_M = 1000000;
static constexpr int LIM_K = 10;

vector<vector<mint>> acc_jordan;

void prev() {
    // spf[i] := i の最小素因数
    vector<int> spf(LIM_M + 1, 0);
    vector<int> primes;
    for (int i = 2; i <= LIM_M; i++) {
        if (spf[i] == 0) {
            spf[i] = i;
            primes.push_back(i);
        }
        for (int p: primes) {
            ll v = (ll)i * p;
            if (v > LIM_M || p > spf[i]) break;
            spf[v] = p;
        }
    }

    // jordan[k][n] := Jordan のトーシェント関数 J_k(n)
    vector jordan(LIM_K + 1, vector<mint>(LIM_M + 1, mint(1)));
    for (int k = 1; k <= LIM_K; k++) {
        for (int n = 2; n <= LIM_M; n++) {
            int m = n / spf[n];
            if (m % spf[n] == 0) {
                jordan[k][n] = jordan[k][m] * mint(spf[n]).pow(k);
            } else {
                jordan[k][n] = jordan[k][m] * (mint(spf[n]).pow(k) - 1);
            }
        }
    }

    // Jordan のトーシェント関数の累積和
    acc_jordan = vector(LIM_K + 1, vector(LIM_M + 2, mint(0)));
    for (int k = 1; k <= LIM_K; k++) {
        for (int n = 0; n <= LIM_M; n++) {
            acc_jordan[k][n + 1] = acc_jordan[k][n] + jordan[k][n];
        }
    }
}

void solve() {
    int N, M, K;
    cin >> N >> M >> K;
    mint ans = 0;

    int l = 1;
    while (l <= M) {
        int q = M / l;
        int r = M / q;
        mint sum_j = acc_jordan[K][r + 1] - acc_jordan[K][l];
        ans += sum_j * mint(q).pow(N);
        l = r + 1;
    }
    cout << ans.val() << '\n';
}

int main() {
    int T;
    cin >> T;
    prev();
    while (T--) solve();
    return 0;
}
0