高效求素数(质数)即素数判定

 

 暴力 代码 就不粘了~~

1、

//Eratosthenes筛法 
//时间复杂度 O(n)~O(nlogn) 
#include<cstdio>
#include<cstring>
#include<cmath> 
#include<iostream>
using namespace std;
const int N=1e8+10;
int n;
bool check[N];
int main(){
    n=1e5+50;
    //scanf("%d",&n);
    //memset(check,0,sizeof check);
    int m=sqrt(n+0.5);
    for(int i=2;i<=m;i++){
        if(!check[i]){
            for(int j=i*i;j<=n;j+=i){
                check[j]=1;
            }
        }
    }
    for(int i=2;i<=n;i++){
        if(!check[i]){
            printf("%d ",i);
        }
    }
    return 0;
}

2、

//欧式筛法 
//时间复杂度 O(n)
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=1e8+10;
int n,tot;
int prime[N/3];
bool check[N];
int main(){
    n=1e7+50;
    //scanf("%d",&n);
    //memset(check,0,sizeof check);
    for(int i=2;i<=n;i++){
        if(!check[i]) prime[++tot]=i;
        for(int j=1;j<=tot&&prime[j]*i<=n;j++){
            check[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
    for(int i=1;i<=tot;i++){
        printf("%d ",prime[i]);
    }
    return 0;
}

   3.费马小定理

//单独测一个较大的素数时,O(1)(常数级别的) 
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#define ll long long
using namespace std;
ll mod;
ll mul(ll a,ll b){/*慢速乘法*/
    ll res=0;
    for(;a;a>>=1,b=(b+b)%mod) if(a&1) res=(res+b)%mod;
    return res;
}
ll fpow(ll a,ll p){/*快速幂 */
    ll res=1;
    for(;p;p>>=1,a=mul(a,a)%mod) if(p&1) res=mul(res,a)%mod;
    return res;
}
bool check(ll n){
    if(n==2) return 1;
    if((n<2)||!(n&1)) return 0;
    mod=n;
    for(ll i=0,x;i<10;i++){/*费马定理+验证法*/
        x=rand();
        if(x%n==0) continue;
        if(fpow(x,n-1)!=1) return 0;
    }
    return 1;
}
int main(){
    srand(time(0));
    ll x;scanf("%lld",&x);
    if(check(x)) puts("Yes");
    else puts("No");
    return 0;
}
原文地址:https://www.cnblogs.com/shenben/p/5458341.html