zoukankan      html  css  js  c++  java
  • Loj#143[模板]质数判定【MillerRabin】

    正题

    题目链接:https://loj.ac/p/143


    题目大意

    给出一个数\(p\),让你判定是否为质数。


    解题思路

    \(Miller-Rabin\)是一种基于费马小定理和二次探测定理的具有较高正确性的高效质数判定算法。
    首先讲一下两个定理

    1. 费马小定理:$$gcd(a,p)=1\ \ \ \Rightarrow\ \ \ a^{p-1}=1(mod\ p)$$
    2. 二次探测定理:若\(p\)是一个素数且有\(0<x<p\)那么有$$x^n=1(mod\ p)\ \ \ \Rightarrow\ \ \ n=1\ or\ p-1$$

    这两个定理我们怎么使用呢,我们先将\(p-1\)分解成\(2^st\)的形式,这样我们对于一个数\(a^t\)就可以进行\(s\)次平方将其变为\(a^{p-1}\)

    再选取一个较小的质数\(a\),然后不停将\(a^t\)平方,每平方一次就使用一次二次探测定理来判定质数。知道\(a^t\)平方\(s\)次后变为\(a^{p-1}\)就再用一次费马小定理。

    当然这样无法完全保证正确性,但是如果我们多拿几个质数试一试就可以大大缩小错误概率。并且目前可以证明在\(int\)范围内使用前\(30\)个质数是保证不会出错的,但是一般代码中为了确保效率会使用少一些素数。

    注意使用\(long\ long\)时乘数可能会超过范围,所以可以用黑科技\(O(1)\)的快速乘来解决


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll pri[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};
    ll ksc(ll a,ll b,ll p){
        a%=p;b%=p;
        ll c=(long double)a*b/p;
        long double ans=a*b-c*p;
        if(ans<0)ans+=p;
        else if(ans>=p)ans-=p;
        return ans;
    }
    ll power(ll x,ll b,ll p){
        ll ans=1;
        while(b){
            if(b&1)ans=ksc(ans,x,p);
            x=ksc(x,x,p);b>>=1;
        }
        return ans;
    }
    bool MB(ll p){
        if(p==2)return 1;
        if(p<2||!(p&1))return 0;
        ll s=0,t=p-1;
        while(!(t&1))
            s++,t>>=1;
        for(ll i=0;i<10&&pri[i]<p;i++){
            ll x=power(pri[i],t,p),k;
            for(ll j=0;j<s;j++){
                k=ksc(x,x,p);
                if(k==1&&x!=1&&x!=p-1)
                    return 0;
                x=k;
            }
            if(x!=1)return 0;
        }
        return 1;
    }
    int main()
    {
        ll x;
        while(scanf("%lld",&x)!=EOF){
            if(MB(x))printf("Y\n");
            else printf("N\n");
        }
    }
    
  • 相关阅读:
    springboot 环境搭建
    Maven工程下构建ssh项目配置
    java动态代理
    java 代理
    java反射
    Java缓存流
    java 输出流
    Java输入数据流
    使用微软 AppFabric 遇到问题
    百度文本编辑器 Ueditor for net 使用七牛存储附件的实现
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14252963.html
Copyright © 2011-2022 走看看