素数

本文介绍了几种常见的素数检测算法,包括简单的遍历检测方法、筛法、6N+1优化法以及更高效的Miller-Rabin素性测试算法。此外,还提供了使用C++和Java实现的大数版本Miller-Rabin测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.判断某个数是否为素数

bool isPrime(int x){
    for(int i=2;i<=sqrt(x*1.0);++i)
        if(x%i==0)
            return false;
    return true;
}

2.筛法

#include<cstring>
#include<cmath>
bool isprime[MAX];
int prime[MAX],cnt;
void doprime(){
    cnt=0;
    memset(isprime,true,sizeof(isprime));
    isprime[0]=isprime[1]=false;
    for(LL i=2;i<=MAX;++i){
        if(isprime[i]){
            prime[cnt++]=i;
            for(LL j=i*i;j<=MAX;j+=i)//i是int可能溢出
                isprime[j]=false;
        }
    }
}

3.6N+1法

int prime[MAX],cnt;
bool isPrime(int k){
    if(k==2)
        return true;
    if(!(k&1))
        return false;
    for(int i=3;i*i<=k;i+=2)
        if(k%i==0)
            return false;
    return true;
}
void doprime(){
    cnt=0;
    prime[cnt++]=2;
    prime[cnt++]=3;
    for(int i=3;i<=MAX;i+=3)
        for(int j=0;j<2;++j)
            if(isPrime(2*(i+j)-1))
                prime[cnt++]=2*(i+j)-1;
}

4.miller_rabin测试

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <algorithm>  
#include <iostream>  
#include <math.h>  

using namespace std;  
const int Times = 10;  
typedef long long LL;  

LL multi(LL a, LL b, LL m)  
{  
    LL ans = 0;  
    a %= m;  
    while(b)  
    {  
        if(b & 1)  
        {  
            ans = (ans + a) % m;  
            b--;  
        }  
        b >>= 1;  
        a = (a + a) % m;  
    }  
    return ans;  
}  

LL quick_mod(LL a, LL b, LL m)  
{  
    LL ans = 1;  
    a %= m;  
    while(b)  
    {  
        if(b & 1)  
        {  
            ans = multi(ans, a, m);  
            b--;  
        }  
        b >>= 1;  
        a = multi(a, a, m);  
    }  
    return ans;  
}  

bool Miller_Rabin(LL n)  
{  
    if(n == 2) return true;  
    if(n < 2 || !(n & 1)) return false;  
    LL m = n - 1;  
    int k = 0;  
    while((m & 1) == 0)  
    {  
        k++;  
        m >>= 1;  
    }  
    for(int i=0; i<Times; i++)  
    {  
        LL a = rand() % (n - 1) + 1;  
        LL x = quick_mod(a, m, n);  
        LL y = 0;  
        for(int j=0; j<k; j++)  
        {  
            y = multi(x, x, n);  
            if(y == 1 && x != 1 && x != n - 1) return false;  
            x = y;  
        }  
        if(y != 1) return false;  
    }  
    return true;  
}  
//java大数版
import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class Main{
        public static final int Times = 10;

        public static BigInteger quick_mod(BigInteger a,BigInteger b,BigInteger m){
                BigInteger ans = BigInteger.ONE;
                a = a.mod(m);
                while(!(b.equals(BigInteger.ZERO))){
                        if((b.mod(BigInteger.valueOf(2))).equals(BigInteger.ONE)){
                                ans = (ans.multiply(a)).mod(m);
                                b = b.subtract(BigInteger.ONE);
                        }
                        b = b.divide(BigInteger.valueOf(2));
                        a = (a.multiply(a)).mod(m);
                }
                return ans;
        }

        public static boolean Miller_Rabin(BigInteger n){
                if(n.equals(BigInteger.valueOf(2))) return true;
                if(n.equals(BigInteger.ONE)) return false;
                if((n.mod(BigInteger.valueOf(2))).equals(BigInteger.ZERO)) return false;
                BigInteger m = n.subtract(BigInteger.ONE);
                BigInteger y = BigInteger.ZERO;
                int k = 0;
                while((m.mod(BigInteger.valueOf(2))).equals(BigInteger.ZERO)){
                        k++;
                        m = m.divide(BigInteger.valueOf(2));
                }
                Random d = new Random();
                for(int i=0;i<Times;i++){
                        int t = 0;
                        if(n.compareTo(BigInteger.valueOf(10000)) == 1){
                                t = 10000;
                        }else{
                                t = n.intValue() - 1;
                        }
                        int a = d.nextInt(t) + 1;
                        BigInteger x = quick_mod(BigInteger.valueOf(a),m,n);
                        for(int j=0;j<k;j++){
                                y = (x.multiply(x)).mod(n);
                                if(y.equals(BigInteger.ONE) && !(x.equals(BigInteger.ONE)) && !(x.equals(n.subtract(BigInteger.ONE)))) return false;
                                x = y;
                        }
                        if(!(y.equals(BigInteger.ONE))) return false;
                }
                return true;
        }

        public static void main(String[] args){
                Scanner cin = new Scanner(System.in);
                while(cin.hasNextBigInteger()){
                        BigInteger n = cin.nextBigInteger();
                        if(Miller_Rabin(n)) System.out.println("Yes");
                        else System.out.println("No");
                }
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值