結果
問題 |
No.458 異なる素数の和
|
ユーザー |
![]() |
提出日時 | 2025-08-15 12:12:03 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 23 ms / 2,000 ms |
コード長 | 3,890 bytes |
コンパイル時間 | 3,493 ms |
コンパイル使用メモリ | 280,256 KB |
実行使用メモリ | 7,716 KB |
最終ジャッジ日時 | 2025-08-15 12:12:08 |
合計ジャッジ時間 | 5,160 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 28 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; bool chmin(auto &a, auto b) { return a > b ? a = b, true : false; } bool chmax(auto &a, auto b) { return a < b ? a = b, true : false; } struct montgomery_modint { using int64 = uint64_t; using int128 = __uint128_t; using modint = montgomery_modint; montgomery_modint() : x(0) {} montgomery_modint(long long v) : x(reduce((int128(v) + MOD) * R)) {} static void set_mod(long long _m) { MOD = _m; R = -int128(MOD) % MOD; INV = get_inv_mod(); } static long long mod() { return MOD; } long long val() const { int64 res = reduce(x); return res >= MOD ? res - MOD : res; } modint& operator+=(const modint &r) { x += r.x; if (x >= (MOD << 1)) x -= (MOD << 1); return *this; } modint& operator-=(const modint &r) { x += (MOD << 1) - r.x; if (x >= (MOD << 1)) x -= (MOD << 1); return *this; } modint& operator*=(const modint &r) { x = reduce(int128(x) * r.x); return *this; } modint& operator/=(const modint &r) { *this *= r.inv(); return *this; } friend modint operator+(const modint &a, const modint &b) { return modint(a) += b; } friend modint operator-(const modint &a, const modint &b) { return modint(a) -= b; } friend modint operator*(const modint &a, const modint &b) { return modint(a) *= b; } friend modint operator/(const modint &a, const modint &b) { return modint(a) /= b; } friend bool operator==(const modint &a, const modint &b) { return a.val() == b.val(); } friend bool operator!=(const modint &a, const modint &b) { return a.val() != b.val(); } modint operator+() const { return *this; } modint operator-() const { return modint() - *this; } modint inv() const { return pow(MOD - 2); } modint pow(int128 k) const { modint a = *this; modint res = 1; while (k > 0) { if (k & 1) res *= a; a *= a; k >>= 1; } return res; } private: int64 x; static int64 MOD, INV, R; static int64 get_inv_mod() { int64 res = MOD; for (int t = 0; t < 5; t++) res *= 2 - MOD * res; return res; } static int64 reduce(const int128 &v) { return (v + int128(int64(v) * int64(-INV)) * MOD) >> 64; } }; typename montgomery_modint::int64 montgomery_modint::MOD, montgomery_modint::INV, montgomery_modint::R; bool miller_rabin(long long m, const vector<long long> ps) { using mint = montgomery_modint; mint::set_mod(m); long long u = 0, v = m - 1; while ((v & 1) == 0) u++, v >>= 1; for (long long p : ps) { if (m <= p) return true; mint x = mint(p).pow(v); if (x != 1) { long long w; for (w = 0; w < u; w++) { if (x == m - 1) break; x *= x; } if (u == w) return false; } } return true; } bool miller_rabin_small(long long m) { return miller_rabin(m, {2, 7, 61}); } bool miller_rabin_large(long long m) { return miller_rabin(m, {2, 325, 9375, 28178, 450775, 9780504, 1795265022}); } bool is_prime(long long m) { if (m <= 1) return false; if (m == 2) return true; if (m % 2 == 0) return false; return m < 4759123141LL ? miller_rabin_small(m) : miller_rabin_large(m); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<int> dp(N + 1, -1 << 30); dp[0] = 0; for (int p = 2; p <= N; p++) { if (is_prime(p)) { for (int i = N; i >= p; i--) { chmax(dp[i], dp[i - p] + 1); } } } cout << max(dp[N], -1) << endl; }