結果
問題 |
No.843 Triple Primes
|
ユーザー |
|
提出日時 | 2025-02-23 20:56:24 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 3 ms / 2,000 ms |
コード長 | 4,004 bytes |
コンパイル時間 | 4,866 ms |
コンパイル使用メモリ | 326,024 KB |
実行使用メモリ | 6,824 KB |
最終ジャッジ日時 | 2025-02-23 20:56:32 |
合計ジャッジ時間 | 6,506 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 42 |
ソースコード
// competitive-verifier: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/0009 #include <iostream> #include <array> #include <cmath> #include <cstdint> #include <vector> /// @brief エラトステネスの篩 /// @see https://qiita.com/peria/items/a4ff4ddb3336f7b81d50 template <int N = (1 << 22)> struct eratosthenes { private: static constexpr int SIZE = N / 30 + (N % 30 != 0); static constexpr std::array<int, 8> kMod30 = {1, 7, 11, 13, 17, 19, 23, 29}; static constexpr std::array<int, 8> C1 = {6, 4, 2, 4, 2, 4, 6, 2}; static constexpr std::array<std::array<int, 8>, 8> C0 = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 0, 2, 0, 2, 2, 1, 3, 1, 1, 2, 1, 1, 3, 1, 3, 3, 1, 2, 1, 3, 3, 1, 4, 2, 2, 2, 2, 2, 4, 1, 5, 3, 1, 4, 1, 3, 5, 1, 6, 4, 2, 4, 2, 4, 6, 1, }; static constexpr std::array<std::array<std::uint8_t, 8>, 8> kMask = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f, 0xfd, 0xdf, 0xef, 0xfe, 0x7f, 0xf7, 0xfb, 0xbf, 0xfb, 0xef, 0xfe, 0xbf, 0xfd, 0x7f, 0xf7, 0xdf, 0xf7, 0xfe, 0xbf, 0xdf, 0xfb, 0xfd, 0x7f, 0xef, 0xef, 0x7f, 0xfd, 0xfb, 0xdf, 0xbf, 0xfe, 0xf7, 0xdf, 0xf7, 0x7f, 0xfd, 0xbf, 0xfe, 0xef, 0xfb, 0xbf, 0xfb, 0xf7, 0x7f, 0xfe, 0xef, 0xdf, 0xfd, 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe, }; public: constexpr eratosthenes() { prime_number.fill(0xff); prime_number[0] = 0xfe; if (int r = N % 30) { if (r < 7) prime_number[SIZE - 1] = 0x1; else if (r < 11) prime_number[SIZE - 1] = 0x3; else if (r < 13) prime_number[SIZE - 1] = 0x7; else if (r < 17) prime_number[SIZE - 1] = 0xf; else if (r < 19) prime_number[SIZE - 1] = 0x1f; else if (r < 23) prime_number[SIZE - 1] = 0x3f; else if (r < 29) prime_number[SIZE - 1] = 0x7f; } const std::uint64_t sqrt_x = std::ceil(std::sqrt(N) + 0.1); const std::uint64_t sqrt_xi = sqrt_x / 30 + 1; for (std::uint64_t i = 0; i < sqrt_xi; ++i) { for (std::uint8_t flags = prime_number[i]; flags; flags &= flags - 1) { std::uint8_t lsb = flags & (-flags); const int ibit = __builtin_ctz(lsb); const int m = kMod30[ibit]; const int pm = 30 * i + 2 * m; for (std::uint64_t j = i * pm + (m * m) / 30, k = ibit; j < SIZE; j += i * C1[k] + C0[ibit][k], k = (k + 1) & 7) { prime_number[j] &= kMask[ibit][k]; } } } } /// @brief 素数判定 bool is_prime(int x) const { switch (x % 30) { case 1: return prime_number[x / 30] >> 0 & 1; case 7: return prime_number[x / 30] >> 1 & 1; case 11: return prime_number[x / 30] >> 2 & 1; case 13: return prime_number[x / 30] >> 3 & 1; case 17: return prime_number[x / 30] >> 4 & 1; case 19: return prime_number[x / 30] >> 5 & 1; case 23: return prime_number[x / 30] >> 6 & 1; case 29: return prime_number[x / 30] >> 7 & 1; } if (x < 6) { if (x == 2) return true; if (x == 3) return true; if (x == 5) return true; } return false; } std::vector<int> prime_numbers(int x) const { if (x < 2) return std::vector<int>(); std::vector<int> res = {2}; for (int i = 3; i <= x; i += 2) { if (is_prime(i)) res.emplace_back(i); } return res; } private: std::array<std::uint8_t, SIZE> prime_number; }; eratosthenes<1000000> pr; int main(void) { int n; std::cin >> n; if (n == 1) { std::cout << 0 << '\n'; return 0; } int ans = 1; for (int i = 3; i <= n && i * i - 2 <= n; ++i) { if (pr.is_prime(i) && pr.is_prime(i * i - 2)) ans += 2; } std::cout << ans << '\n'; return 0; }