すべての種類(e)に良い(XIN)の友人は数論、絶望3 ---リニアふるいとその役割へのエントリから最も重要な設定しました

元の記事は、ダイにカードを感じ、かつ迅速にQAQを外に移動されています。

题目描述
【题意】
素数表如下:
2、3、5、7、11、13、17…………
有n次询问,每次问第几个素数是谁?
【输入格式】
第一行n(1<=n<=10000)
下来n行,每行一个整数pi,表示求第pi个素数。1<=pi<=100 0000
【输出格式】
每次询问输出对应的素数。
【样例输入】
3
1
4
7
【样例输出】
2
7
17

ふるい、ふるいおよびオイラー式Aのふるい線形2つの素数があります。

エジプト風の画面

私たちは、この数の平方根に等しい、という数が素数でない場合、それは最低限の品質係数よりも小さくする必要があります知っています。

詳細に説明していない、と考えるのは簡単です。

そして、見つける(\ 1)\(B \)\素数、私たちは、知ることができます\(1 \)\(B \)最小素因数合成数は確かに少ないです(\ \ sqrtのB)\、その後、我々は単に必要です\(\ sqrtのB \)のためのすべての素数と暴力小さなスペースの上に、複雑です\(O(nloglogn)\)

for(int  i=2;i<=sqrt(b);i++)
{
    if(mp[i]==false)//为素数
    {
        for(int  j=i;j<=b;j+=i)mp[j]=true;
    }
}

多くの場合、魔法カードのバージョンがあるとします。

for(register  int  i=3;i<=sqrt(m);i+=2)
{
    if(a[i/2]==true)
    {
        for(register  int  j=i*3;j<=m;j+=i*2)a[j/2]=false;
    }
}

しかし、それはまだ最適化することができ、より毎回ジャンプ\(I ^ 2 \)が小さい素数の前面が更新する必要があるため、ジャンプし始めました。

for(int  i=2;i<=sqrt(b);i++)
{
    if(mp[i]==false)//为素数
    {
        for(int  j=i*i;j<=b;j+=i)mp[j]=true;
    }
}

魔法のカードのこのバージョンは、多くの場合、QAQを追加しないでください。

右の複雑さ、一見調和級数と証明するために、私はQAQしません。

オイラー画面

メイン画面の背後にあるタイトルオイラー複雑\(O(n)は、\)

これは非常に魔法であり、第1のコードを与えます:

#include<cstdio>
#include<cstring>
#define  N  21000000
using  namespace  std;
int  ins[2100000];//素数表
bool  mp[N];
int  main()
{
    for(int  i=2;i<=20000000;i++)
    {
        if(!mp[i])ins[++ins[0]]=i;//存入素数表
        for(int  j=1;j<=ins[0]  &&  ins[j]*i<=20000000;j++)
        {
            mp[ins[j]*i]=true;
            if(i%ins[j]==0)break;
        }
    }
    int  n;scanf("%d",&n);
    for(int  i=1;i<=n;i++)
    {
        int  x;scanf("%d",&x);
        printf("%d\n",ins[x]);
    }
    return  0;
}

多くの人々はこれを疑います

if(i%ins[j]==0)break;

場合は、\(ins_ {J} | I \) あなたは、なぜ別れることができますか?我々が設定よう\(I \)\(D * ins_ {J} \)に設けられ、\(K> Jを\)、\ (I * ins_ {K} = D * ins_ {J} * ins_ {K} = (D * ins_ {K})* ins_ {J} \)我々は知ることができる\(D * ins_ {K}> D * ins_ {J} \) およびそれ以降のサイクルの間、\(I *はins_ {K } \)タグ付け繰り返され、その後、あなたは絶妙なので、言葉を破ることができます。

スーパーカードチャン版:

for(register  int  i=3;i<=m;i+=2)
{
    if(a[i/2]==true)b[++k]=i;
    for(register  int  j=1;j<=k  &&  b[j]*i<=m;++j)
    {
        a[b[j]*i/2]=false;
        if(i%b[j]==0)break;
    }
}

もちろん、注意カードが多いバージョン。

実際には、Iファック

証明の複雑さと自然

合成数の場合は\(X- \) その最小除数設定\(yは\) その後、彼はより大きくないかもしれません(Y \)\およそ数\(Z \)それを見つけるには?

その結果、(\ {X-FRAC}} * \ {Z Z \)が、|(\ {Z} \ Y-X-FRAC {\})ので見つけ、\(xは\)毎に、時間を終了しますこれらの数字は、おそらく最小除数を発見することが、その結果である(\ O(N))\

それはおよそいくつかのふるいの唯一の最小値であるので言及は、それは多くの場合、画面乗法関数に使用されています。

また、自然界にも頻繁に使用されているがあります:If \(私は\)素数である(\ x)が\(つまりに、ある割り切れる\(IF \) その後、) 私は* X \)\素因数でありますインデックスがより大きくなければなりません(1 \)\

オイラーふるい乗法機能

乗法関数定義を確認することができ、「様々な友人(E)良い(XIN)のエントリから絶望4の総数理論、(メビウス反転とディリクレ畳み込み)を設定します。」

一般的なタイプの機能の製品について:\(F(I)F(J)= F()のIJ \)場合\(GCD(I、J)= 1 \。)

我々は、各デジタル用CAN (I \)\堆積される\(低\)値を、約数倍の最小の電力を表し、すなわち、デジタル分割するために:\(P_ ^ {} 1. 1 {{} A_。 ^ {a_iを... P_I}}(P_1 <P_2 <P_3 <...)\)(\ (P \)が素数である)、次いで\(低\)堆積物である(P_1 ^ {A_1} \ \ )

そして、それは(も物事をプッシュするために最も必要とする乗法関数)関数値の処理能力が続いているときに我々は素数を見つけたとき。

したがって、デジタル\(X \)に分解することができる\(\ FRAC {X} { low_x} \) と\(low_x \)

フル乗法関数では、存在しません\(低\)の値、および特定の自然といくつかの完全に乗法機能のために、我々はいくつかの魔法のパロディの使用を省略することができます\(低\) 一般的な方法をそれがためである\(I \) それぞれ質量と等分割、ことなく数の分割を議論している\(ファイ(Φ)\)機能。

詳細については、オイラー関数を参照してください。

おすすめ

転載: www.cnblogs.com/zhangjianjunab/p/11848139.html