FZU 1649 Prime number or not (米勒拉宾大素数判断+快速幂取模+随机数模板)

本文介绍了一种高效的大素数判定方法——米勒拉宾算法,该算法适用于处理高达1亿亿的数据规模。通过随机选取多个基数进行费马小定理的验证,算法能够以高概率判断一个数是否为素数。文章提供了详细的算法流程和C语言实现代码。
摘要由CSDN通过智能技术生成

http://acm.fzu.edu.cn/problem.php?pid=1649

这里关键的问题在于数据达到了1亿亿,没办法用普通的方法进行运算,所以这里用到了米勒拉宾大素数判定方法。

算法流程:根据费马小定理,a^(n-1)mod n==1,1<a<n,n为奇素数。随机在1~n的范围内取一个数a,进行式子的判定,返回1,就是伪素数,否则就是合数。因为伪素数是素数的可能性为3/4,也就是正确率是1-1/4^k,所以我们要按定一个k使得正确率尽可能得大。所以要多次重复取随机数,然后判定。

文字代码:

1:重复MAX次运算

2:在1~n中取得随机数a

3:计算a^(n-1)mod n?=1,在这个计算里,注意到n可能很大,所以a^(n-1)可能越界,就想到用快速幂来边乘,边取模,但是又发现在n很大的时候,a*a都有可能溢出,所以想到了用快速幂的方法,进行快速积取模,边加边取模。这里的两个快速可避免溢出

4:在3中可得到的数如果为1,则在循环未结束前继续从2开始操作,否则直接返回0,表示n是合数

5:如果上面的循环能完整做完,说明n已经是强伪素数,我们可以返回1,判定为素数。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 10
__int64 muti(__int64 a,__int64 b,__int64 m)
{
        __int64 ans=0;
        while(b)
        {
                if(b&1)
                ans=(ans+a)%m;
                a=2*a%m;
                b/=2;
        }
        return ans;
}
__int64 pow(__int64 a,__int64 b,__int64 m)
{
        __int64 ans=1;
        while(b)
        {
                if(b&1)
                ans=muti(ans,a,m);
                a=muti(a,a,m);//二进制。快速幂的思想 
                b/=2;
        }
        return ans;
}
int miller_rabin(long long n)
{
    __int64 i,a;
    if(n==2)
        return 1;
    if(n<2||!(n&1))
        return 0;
    srand((unsigned)time(NULL));
    for(i=1;i<=MAX;i++)
    {
        a=rand()%(n-2)+1;
        if(pow(a,n-1,n)!=1)
            return 0;
    }
    return 1;
}
int main()
{
    __int64 n;
    while(scanf("%I64d",&n)!=EOF)
    if(miller_rabin(n))
    printf("It is a prime number.\n");
    else printf("It is not a prime number.\n");
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/huzhenbo113/p/3261704.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值