結果

問題 No.2075 GCD Subsequence
ユーザー cureskolcureskol
提出日時 2024-11-07 10:44:18
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,502 ms / 4,000 ms
コード長 2,710 bytes
コンパイル時間 3,139 ms
コンパイル使用メモリ 255,724 KB
実行使用メモリ 11,776 KB
最終ジャッジ日時 2024-11-07 10:44:43
合計ジャッジ時間 23,335 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 15 ms
11,648 KB
testcase_01 AC 14 ms
11,648 KB
testcase_02 AC 15 ms
11,648 KB
testcase_03 AC 14 ms
11,648 KB
testcase_04 AC 15 ms
11,648 KB
testcase_05 AC 15 ms
11,648 KB
testcase_06 AC 15 ms
11,648 KB
testcase_07 AC 15 ms
11,648 KB
testcase_08 AC 205 ms
11,648 KB
testcase_09 AC 320 ms
11,776 KB
testcase_10 AC 198 ms
11,648 KB
testcase_11 AC 266 ms
11,648 KB
testcase_12 AC 251 ms
11,648 KB
testcase_13 AC 166 ms
11,648 KB
testcase_14 AC 255 ms
11,648 KB
testcase_15 AC 186 ms
11,648 KB
testcase_16 AC 193 ms
11,648 KB
testcase_17 AC 320 ms
11,648 KB
testcase_18 AC 1,396 ms
11,520 KB
testcase_19 AC 1,376 ms
11,648 KB
testcase_20 AC 1,419 ms
11,648 KB
testcase_21 AC 1,391 ms
11,648 KB
testcase_22 AC 1,398 ms
11,648 KB
testcase_23 AC 1,396 ms
11,648 KB
testcase_24 AC 1,426 ms
11,776 KB
testcase_25 AC 1,402 ms
11,648 KB
testcase_26 AC 1,385 ms
11,648 KB
testcase_27 AC 1,431 ms
11,648 KB
testcase_28 AC 1,502 ms
11,648 KB
testcase_29 AC 15 ms
11,648 KB
testcase_30 AC 15 ms
11,648 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <atcoder/modint>
#include <bits/stdc++.h>
using mint = atcoder::modint998244353;

#include <bits/stdc++.h>

class Prime {
    static inline std::vector<int> primes_, minimum_prime_factor;
    static inline bool is_prepared = false;

  public:
    static void build(int N) {
        assert(!is_prepared);
        is_prepared = true;
        minimum_prime_factor.resize(N + 1);
        std::iota(minimum_prime_factor.begin(), minimum_prime_factor.end(), 0);
        for (int p : std::views::iota(2, N + 1)) {
            if (minimum_prime_factor[p] != p)
                continue;
            primes_.push_back(p);
            if (N / p < p)
                continue;
            for (int q = p * p; q <= N; q += p)
                if (minimum_prime_factor[q] == q)
                    minimum_prime_factor[q] = p;
        }
    }

    static const std::vector<int> &primes() {
        assert(is_prepared);
        return primes_;
    }

    static std::vector<std::pair<int, int>> prime_factors(int n) {
        assert(is_prepared);
        assert(n < minimum_prime_factor.size());
        std::vector<std::pair<int, int>> res;
        while (n != 1) {
            int p = minimum_prime_factor[n];
            if (res.size() and res.back().first == p)
                res.back().second++;
            else
                res.emplace_back(p, 1);
            n /= p;
        }
        return res;
    }

    static std::vector<int> divisors(int n) {
        assert(is_prepared);
        assert(n < minimum_prime_factor.size());
        if (n == 1)
            return {1};
        int p = minimum_prime_factor[n];
        int cnt = 0;
        while (minimum_prime_factor[n] == p)
            n /= p, cnt++;

        auto res = divisors(n);
        int s = res.size();
        res.reserve(s * (cnt + 1));
        for (int i : std::views::iota(0, s)) {
            int d = res[i];
            for (int _ : std::views::iota(1, cnt + 1))
                res.push_back(d *= p);
        }
        return res;
    }
};

constexpr int MAX = 1000000;

int main() {
    int n;
    std::cin >> n;

    std::vector<mint> dp(MAX + 1, 0);
    Prime::build(MAX);

    while (n--) {
        int a;
        std::cin >> a;
        for (const auto &[p, e] : Prime::prime_factors(a))
            for (int _ : std::views::iota(0, e - 1))
                a /= p;

        mint sum = mint::raw(1);
        for (int d : Prime::divisors(a))
            if (d != 1)
                if (Prime::prime_factors(d).size() & 1)
                    sum += dp[d];
                else
                    sum -= dp[d];

        for (int d : Prime::divisors(a))
            dp[d] += sum;
    }

    std::cout << dp[1].val() << std::endl;
}
0