素数

  打印素数表,超级素数1亿以内,时间复杂度2.4s

#include <cstdio>
#include <time.h>
const int N = 100000000;
bool isprime[N];
int p[100000000];
int suprime[100];
int np;
void sup(int n){   //判断超级素数
    int t=n;
    if(n<10)    {suprime[np++]=n ,printf("%d,",n);return;}
    if(n<20)    return ;
    while(n){
        n/=10;
        if(isprime[n]) return;
    }
    suprime[np++]=t;
    printf("%d,",t);
}
void prime(int n) //生成一个我们想要的小范围的素数表,用于素数判断
{
    int np = 0;
    for (int i = 2; i <= n; i++)
    {
        if (!isprime[i]) p[np++] = i,sup(i);
        for (int j = 0; j < np && p[j]*i <= n; j++)
        {
            isprime[p[j]*i] = 1;
            if( i % p[j] == 0) break;
        }
    }
    printf("



%d
",np);
}

int main(){
    freopen("data.out","w",stdout);
    int n;
    long long start,end;
    scanf("%d",&n);
    start = clock();
    prime(n);
    end = clock();


    printf("//运行耗时%.2f秒
",(end-start)*1.0/1e3);
}

判断素数:

      费马素数测试
费马小定理:
  有N为任意正整数,P为素数,且N不能被P整除(显然N和P互质),
则有:
  N^P%P=N(即:N的P次方除以P的余数是N)
公式变形:  (N^P-N)%P=0  ==》 N(N^(P-1)-1)%P=0

因为 N(N^(P-1)-1) 是p和n公倍数

设M为是p*n的倍数。

则N(N^(P-1)-1) = M*N*P ==》N^(P-1)-1 =M*P ==》(N^(P-1)-1)%P=0 ==》N^(P-1)%P=1  ( 积模分解公式

最终推出  定理:N^(P-1)%P=1 

利用这个公式

求解:

int Montgomery(int n,int p,int m) //蒙格马利快速幂模算法,用于后面素数判断
{ //快速计算(n^e)%m的值,即逐次平方法
    int k=1;
    n%=m;
    while(p!=1)
    {
        if(0!=(p&1))
            k=(k*n)%m;
        n=(n*n)%m;
        p>>=1;
    }
return(n*k)%m;
}

bool IsPrime(int n) //利用蒙格马利快速幂模算法来判断素数
{
    if ( n < 2 )
    { // 小于2的数即不是合数也不是素数
        return false;
    }
    for (int i=0;i<np;++i)
    { // 按照素数表中的数对当前素数进行判断
        if (1!=Montgomery(p[i],n-1,n))//蒙格马利算法
            return false;
    }
    return true;
}
原文地址:https://www.cnblogs.com/acmtime/p/5720619.html