結果
問題 | No.36 素数が嫌い! |
ユーザー | nok0 |
提出日時 | 2021-06-14 11:33:55 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2 ms / 5,000 ms |
コード長 | 4,371 bytes |
コンパイル時間 | 2,400 ms |
コンパイル使用メモリ | 213,256 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-06-06 14:31:37 |
合計ジャッジ時間 | 3,285 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 2 ms
5,376 KB |
testcase_13 | AC | 2 ms
5,376 KB |
testcase_14 | AC | 2 ms
5,376 KB |
testcase_15 | AC | 1 ms
5,376 KB |
testcase_16 | AC | 2 ms
5,376 KB |
testcase_17 | AC | 1 ms
5,376 KB |
testcase_18 | AC | 2 ms
5,376 KB |
testcase_19 | AC | 2 ms
5,376 KB |
testcase_20 | AC | 2 ms
5,376 KB |
testcase_21 | AC | 2 ms
5,376 KB |
testcase_22 | AC | 2 ms
5,376 KB |
testcase_23 | AC | 2 ms
5,376 KB |
testcase_24 | AC | 2 ms
5,376 KB |
testcase_25 | AC | 2 ms
5,376 KB |
testcase_26 | AC | 2 ms
5,376 KB |
testcase_27 | AC | 2 ms
5,376 KB |
testcase_28 | AC | 2 ms
5,376 KB |
testcase_29 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> #include <atcoder/modint> namespace inner { using u32 = uint32_t; using u64 = uint64_t; using i64 = int64_t; using u128 = __uint128_t; u64 gcd_impl(u64 n, u64 m) { constexpr u64 K = 5; for(u32 i = 0; i < 80; ++i) { u64 t = n - m; u64 s = n - m * K; bool q = t < m; bool p = t < m * K; n = q ? m : t; m = q ? t : m; if(m == 0) return n; n = p ? n : s; } return gcd_impl(m, n % m); } u64 gcd_pre(u64 n, u64 m) { for(u32 i = 0; i < 4; ++i) { u64 t = n - m; bool q = t < m; n = q ? m : t; m = q ? t : m; if(m == 0) return n; } return gcd_impl(n, m); } u64 gcd_fast(u64 n, u64 m) { return n > m ? gcd_pre(n, m) : gcd_pre(m, n); } struct modint64 { using u64 = uint64_t; public: static u64 mod; static u64 r, n2; static void set_mod(u64 m) { mod = m; n2 = -u128(m) % m; r = get_r(); assert(r * mod == 1); } modint64() : a(0) {} modint64(const i64 &b) : a(reduce((u128(b) + mod) * n2)) {} modint64 &operator+=(const modint64 &b) { if(i64(a += b.a - 2 * mod) < 0) a += 2 * mod; return *this; } modint64 &operator-=(const modint64 &b) { if(i64(a -= b.a) < 0) a += 2 * mod; return *this; } modint64 &operator*=(const modint64 &b) { a = reduce(u128(a) * b.a); return *this; } modint64 operator+(const modint64 &b) const { return modint64(*this) += b; } modint64 operator-(const modint64 &b) const { return modint64(*this) -= b; } modint64 operator*(const modint64 &b) const { return modint64(*this) *= b; } modint64 pow(u128 n) const { modint64 ret(1), mul(*this); while(n > 0) { if(n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } u64 val() const { u64 ret = reduce(a); return ret >= mod ? ret - mod : ret; } static u64 get_mod() { return mod; } private: u64 a; static u64 get_r() { u64 ret = mod; for(u32 i = 0; i < 5; i++) ret *= 2 - mod * ret; return ret; } static u64 reduce(const u128 &b) { return (b + u128(u64(b) * u64(-r)) * mod) >> 64; } }; typename modint64::u64 modint64::mod, modint64::r, modint64::n2; u64 rnd() { static u64 x = 10150724397891781847ull; x ^= x << 7; return x ^= x >> 9; } bool is_prime(const u64 n) { if(~n & 1) return n == 2; if(n < (1ll << 30)) return atcoder::internal::is_prime_constexpr(n); u64 d = n - 1; while(~d & 1) d >>= 1; if(modint64::get_mod() != n) modint64::set_mod(n); for(const u64 a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) { if(n <= a) break; modint64 t = d, y = modint64(a).pow(d); while(t.val() != n - 1 and y.val() != 1 and y.val() != n - 1) { y *= y; t *= 2; } if(y.val() != n - 1 and ~t.val() & 1) return false; } return true; } u64 pollard_rho(const u64 n) { if(~n & 1) return 2; if(is_prime(n)) return n; if(modint64::get_mod() != n) modint64::set_mod(n); modint64 R, one = 1; auto f = [&](modint64 x) { return x * x + R; }; auto rng = [&]() { return rnd() % (n - 2) + 2; }; for(;;) { modint64 x, y(rng()), ys, q = one; R = rng(); u64 g = 1; constexpr u32 m = 128; for(u32 r = 1; g == 1; r <<= 1) { x = y; for(u32 i = 0; i < r; i++) y = f(y); for(u32 k = 0; g == 1 and k < r; k += m) { ys = y; for(u32 i = 0; i < m and i < r - k; i++) q *= x - (y = f(y)); g = gcd_fast(q.val(), n); } } if(g == n) do g = gcd_fast((x - (ys = f(ys))).val(), n); while(g == 1); if(g != n) return g; } exit(1); } std::vector<u64> factorize(const u64 n) { if(n == 1) return {}; if(is_prime(n)) return {n}; auto d = pollard_rho(n); auto res = factorize(d); auto sub = factorize(n / d); std::copy(sub.begin(), sub.end(), std::back_inserter(res)); return res; } }; // namespace inner using inner::is_prime; template <typename T> std::vector<T> factorize(const T n) { auto tmp = inner::factorize(n); std::vector<T> res{tmp.begin(), tmp.end()}; std::sort(res.begin(), res.end()); return res; } template <typename T> std::vector<std::pair<T, int>> pair_factorize(const T n) { std::vector<std::pair<T, int>> res; auto tmp = inner::factorize(n); if(tmp.empty()) return tmp; T now = tmp.front(); int cnt = 0; for(auto &v : tmp) { if(now == tmp) cnt++; else { res.emplace_back(now, cnt); now = v; cnt = 1; } } res.emplace_back(now, cnt); return res; } int main() { long long n; std::cin >> n; std::cout << (factorize(n).size() >= 3 ? "YES\n" : "NO\n"); }