結果

問題 No.3651 K-th Sum of Divisors
コンテスト
ユーザー Guran08
提出日時 2026-08-28 22:35:37
言語 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
結果
WA  
実行時間 -
コード長 3,843 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,273 ms
コンパイル使用メモリ 343,720 KB
実行使用メモリ 6,272 KB
最終ジャッジ日時 2026-08-28 22:35:46
合計ジャッジ時間 7,622 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 10 WA * 15 RE * 30
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
// using mint = modint998244353;
//using mint = modint1000000007;
using ll = long long;
using P = pair<ll, ll>;
using T = tuple<ll, ll, ll>;
template<typename T_>bool chmax(T_& a, const T_& b) { if (a < b) { a = b;return true; } else { return false; } }
template<typename T_>bool chmin(T_& a, const T_& b) { if (a > b) { a = b;return true; } else { return false; } }

#ifdef LOCAL
template<class T, class U> ostream& operator<<(ostream& o, const pair<T, U>& p) { return o << "(" << p.first << ", " << p.second << ")"; }
template<class... T> ostream& operator<<(ostream& o, const tuple<T...>& t) { o << "("; apply([&o](auto&&... a) { int c = 0; (((o << (c++ ? ", " : "") << a)), ...); }, t); return o << ")"; }
template<class V> auto operator<<(ostream& o, const V& v) -> std::enable_if_t<!std::is_same_v<V, std::string> && !std::is_same_v<V, std::string_view>, decltype(v.begin(), o)> { o << "{"; int c = 0; for (auto& x : v) o << (c++ ? ", " : "") << x; return o << "}"; }
#define dbg(...) cerr<<"["<<#__VA_ARGS__<<"]: ",([](auto&&... a){((cerr<<a<<' '),...);})(__VA_ARGS__),cerr<<'\n'
#else
#define dbg(...) void(0)
#endif

const int di[] = { -1,0,1,0 };
const int dj[] = { 0,-1,0,1 };
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;

struct Eratosthenes {
    // テーブル
    vector<bool> isprime;

    // 整数 i を割り切る最小の素数
    vector<int> minfactor;

    // コンストラクタで篩を回す
    Eratosthenes(int N) : isprime(N + 1, true),
        minfactor(N + 1, -1) {
        // 1 は予めふるい落としておく
        isprime[1] = false;
        minfactor[1] = 1;

        // 篩
        for (int p = 2; p <= N; ++p) {
            // すでに合成数であるものはスキップする
            if (!isprime[p]) continue;

            // p についての情報更新
            minfactor[p] = p;

            // p 以外の p の倍数から素数ラベルを剥奪
            for (int q = p * 2; q <= N; q += p) {
                // q は合成数なのでふるい落とす
                isprime[q] = false;

                // q は p で割り切れる旨を更新
                if (minfactor[q] == -1) minfactor[q] = p;
            }
        }
    }

    // 高速素因数分解
    // pair (素因子, 指数) の vector を返す
    vector<pair<int, int>> factorize(int n) {
        vector<pair<int, int>> res;
        while (n > 1) {
            int p = minfactor[n];
            int exp = 0;

            // n で割り切れる限り割る
            while (minfactor[n] == p) {
                n /= p;
                ++exp;
            }
            res.emplace_back(p, exp);
        }
        return res;
    }

    // 高速約数列挙
    vector<int> divisors(int n) {
        vector<int> res({ 1 });

        // n を素因数分解 (メンバ関数使用)
        auto pf = factorize(n);

        // 約数列挙
        for (auto p : pf) {
            int s = (int)res.size();
            for (int i = 0; i < s; ++i) {
                int v = 1;
                for (int j = 0; j < p.second; ++j) {
                    v *= p.first;
                    res.push_back(res[i] * v);
                }
            }
        }
        return res;
    }
};

int main() {
    // エラトステネスの篩
    Eratosthenes er(100003);

    ll n, k; cin >> n >> k;
    set<int> st;
    vector<int> ans;
    ll x = n, t = 0;
    while (!st.contains(x)) {
        t++;
        st.emplace(x);
        ans.push_back(x);
        auto pf = er.divisors(x);
        ll cnt = 0;
        for (int i = 0; i < (int)pf.size(); ++i) {
            cnt += pf[i];
        }
        x = cnt % 100003;
    }
    k--;
    dbg(k, t);

    cout << ans[k % t] << "\n";
}
0