エラトステネスの篩の練習問題に良さそう
問題概要
以上 以下の素数の組 であって、
を満たすものの個数を求めよ。
制約
考えたこと
のときは明らかにダメ。
また、偶数かつ素数である整数は 2 のみであることに注意する。 がともに奇数とすると は偶数となる。よって となるが、 を満たす解は しかない。よって がともに奇数であることはありえない。
以上から、 または であるとしてよい。ここでは として解いて最後に 2 倍することにする。 の場合をあらかじめ特別扱いしておく。
を満たす奇素数 をすべて求める問題へと帰着された。次のように解ける。
- あらかじめエラトステネスの篩によって 以下のすべての整数について、素数かどうかを求めておく ()
- を満たすすべての素数 に対して が素数ならば、答えに加算する
全体で計算量は となる。
コード
#include <bits/stdc++.h> using namespace std; vector<bool> isprime; vector<int> Era(int n) { isprime.resize(n, true); vector<int> res; isprime[0] = false; isprime[1] = false; for (int i = 2; i < n; ++i) isprime[i] = true; for (int i = 2; i < n; ++i) { if (isprime[i]) { res.push_back(i); for (int j = i*2; j < n; j += i) isprime[j] = false; } } return res; } long long solve(long long N) { Era(1000000); if (N == 1) return 0; long long res = 1; // (2, 2, 2) for (long long r = 3; r*r - 2 <= N; ++r) { if (isprime[r] && isprime[r*r-2]) res += 2; } return res; } int main() { int N; cin >> N; cout << solve(N) << endl; }