[素数/アドバンストふるいアルゴリズム-C ++]

今日はのは、素数決意/ふるい法についてお話しましょう。
各OIerについて、実際の長い過程で、だから、今日私たちが暴力への効率的ないくつかの判断を共有し、すべての素数がOIerが操作を持つべきである/スクリーンを決定、その後、私たちの目には表示されませんすることができ素数ではありません法律/ふるい法。
精神障害例えば、1からnまたは列挙列挙に\(\ SQRT {N} \ ) アルゴリズム話せません。


オイラー画面

オイラー基本画面は、前処理がO(1)クエリ、多周波の場合のクエリ、狭い範囲とすることができる後に、リニア方式の画面です。
基本的な考え方:各結合は、タグ最大要因の数(または最小品質係数)を可能にしました。
これを確実にするために、我々は中に入れるためにはプライム配列、品質チェックの数を開きます。その役割は数列挙することです\(私は\) 連続的に逓倍することが可能
マーキング工程では、場合、合成数をマークするために、アレイ内のプライム要素| \(私は\プライム[J])は、この丸印を停止します。
前処理セクション:

for(int i=2;i<=n;i++)
{
    if(!book[i])prime[++ind]=i;
    for(int j=1;j<=ind;j++)
    {
           if(i*prime[j]>n) break;
           book[i*prime[j]]=1;
           if(!i%prime[j])break;
    }
}

前処理の後、\(プライム[I]は(私のLeq INDを\)\) Nより小さい素数を表します。
注意:ここで使用するのが最善ではありません\(ブック[i]は\)に直接びっくりWA DAの音になります出力を決定!


2.別の方法

彼らは名前が最初にそれをすることだったのか分からない...そうなので
、この決意の方法が少し形而上学です...私たちにプッシュを与えます。
:証明:以下のようにしましょうX≧1は、5以上の自然数で表されている
...... 1,6x-6X、6X + 1,6x + 2,6x + 3,6x + 5,6 + 4,6、Xを( X + 1)、6(X + 1)+1 ......

これは明らかに2(3X + 1)、3ので、すなわち、両側6の倍数ではない、ことを6X 6X + 2,6x + 3,6x + 4の辺の数を示す (2X + 1)、2(3X + 2)、彼らは素数でない必要があり、その後、自身6X取り出し、明らかに、その両側に隣接して表示する素数が6倍から来ています。ここで注意すべき点は、ある両側は、6つの主要な倍数に必ずしも隣接していません

この時点で、缶素数を判定単位として6に早送り(2)ループiは決意速度を加速するために、6のステップ増加を++、理由はあなたが決定された数を望む場合にはnは、nは1-6X又はなければならない、すなわち方法6X + 1、6I-1,6iを循環させるための、6Iの形で+ 1,6i + 2,6i + 3,6i + 4、 N缶6I場合、6I + 2,6i + 4分割し、少なくともn個我々は、偶数を有するが、6X-1または6Xの形で+ 1は、それが確立されていない、明らかに奇数である。また、n + 3 6Iこと割り切れる、nは分割することができるが、3で割り切れる6倍、少なくとも3である場合、これ6X-1又は6X + 1(すなわち、n)が確立されていない3、によって分割することができません。要約すると、ループのみケース6I-1及び6I + 1を検討する必要、即ち、サイクルが決意のそれぞれに6、ここで、ループ変数kとK + 2段階に設定することができます。

コードの実装は非常に単純ですが、二つの状況が特別な文を必要があることに留意すべきです。

1.この数は1であり、偽に戻す必要がある。
2.この数は2又は3であり、trueを返す必要があります。

右側に抜け出すために上記のアイデアを他に従い、以下のように、コードは次のとおりです。

bool isPrime_3(int num)
{
    if(num==1)
        return 0;
    if(num==2||num==3)
        return 1;
    if(num%6!=1&&num%6!=5)
        return 0;
    int tmp=sqrt(num);
    for(int i=5;i<=tmp;i+=6)
        if(num%i==0||num%(i+2)==0)
            return 0;
    return 1;
}

この方法の速度は、すぐに裁判官の判断すべき\(40W \)の数が唯一の素数必要であれば\(0.099s \)

分析方法3.Miller・ラビン

この方法の騎士は、私が理解するにはあまりにも多くを持っているが、それは形而上学であると述べていません!
コードはまた、より複雑です

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll qpow(ll x,ll y,ll p)//x^y mod p
{
    ll ans=1,m=x;
    while(y)
    {
        if(y&1)ans*=m;
        ans%=p;
        m*=m;
        m%=p;
        y>>=1;
    }
    return ans;
}
bool check(ll x,ll y,ll p)
{
    ll q=qpow(x,y,p);
    if(q!=1&&q!=p-1)return 0;
    if(q==p-1)return 1;
    if(q==1&&(y&1))return 1;
    return check(x,y>>1,p);
}
bool mil(ll x)
{
    if(x<=1)return 0;
    if(x==2||x==7||x==61||(check(2,x-1,x)&&check(7,x-1,x)&&check(61,x-1,x)))/*底数RP++*/return true;
    return 0;
}
int main()
{
    int n,m;
    ll k;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>k;
        if(mil(k))cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}

明らかに、改変することができる第二の数は、また、あなたの(好ましくは、選択された素数)の正しい比率を決定した場合ミル機能
を選択した場合\(3 \)基板として、130ワット内のデータによって、もし\(2,7,61 \)を基質として、以下4.7億データ(実際には形而上学)することができ
、もちろん、基板などの他の素数の選挙は、エラー率は、非常に低い場合にのみ\(4 ^ { - K} \)
他の人がそれを話すことはありません...それは、後続の深い理解した後に更新することができます。
OV。

おすすめ

転載: www.cnblogs.com/moyujiang/p/11236379.html