数値が素数かどうかを高速に判定する
これまで、ある数値
n
が素数であるかどうかを調べる方法としては、基本的に割り算を使った線形探索を行っていました。つまり、n
を大きくすれば、その素数判定に必要な操作回数は比例的に増えていく(ある定数倍)という仕組みでした。最悪のケース(たとえば 51 や 107 のように n
自体が素数のケース)を考えると、私たちのアルゴリズムは n/4
回程度の演算を行っていました。これは、
n
を 10 倍にすると、素数判定のための操作回数も 10 倍になり、100 倍にすると 100 倍になるということを意味しています。つまり、アルゴリズムの実行時間は n
に比例していたわけです。では、もっと速く判定する方法はないのでしょうか。よく見ると、まだ無駄なチェックが多いように思われます。 を用いる方法:
n
に約数 d
があるとします。つまり、
n
は d
で割り切ることができ、d
と はどちらも整数です。そして、d
と のどちらか一方は必ず 以下になります。素数判定をする際、1 と n
以外の割り切れる数が存在するかどうかを調べたいわけですから、d
と の小さいほうを探せば十分です。つまり、そのどちらかは 以下になるため、ループを までで止めれば判定が可能です。これは大きな改良です。これまでは
n
回程度かかっていたものを、 回で済ませられるわけです。たとえば、あるアルゴリズムが 10 年(3650 日)かかっていた計算を、n
ではなく の回数だけ演算するように最適化できるとしたら、2 か月(61 日)で完了するイメージです。ある数が素数かどうかを判定する、より進んだアルゴリズムはある?
はい!詳細は <a href="https://cp-algorithms.com/algebra/primality_tests.html">Algorithms for Competitive Programming</a> で読むことができます。
n
の増加に応じた演算回数が ではなく、対数的に増えるアルゴリズムも存在します。 入力
The first line of the input contains a single integer
n
(1 ≤ n ≤ ). 出力
The program should print
Yes
in case n
is prime and No
otherwise. Examples
Input | Output |
1 | No |
11 | Yes |
353557 | Yes |
34134741 | No |
902468477 | No |
Constraints
Time limit: 2 seconds
Memory limit: 512 MB
Output limit: 1 MB