zoukankan      html  css  js  c++  java
  • 简单数论(五)------Miller Rabin 素数判定

    本来简单数论5准备写高斯消元的但是咕掉了,所以简单数论5改成了素数判定,高斯消元之后直接补到(四)里面

     简单数论(五)------Miller Rabin 素数判定

     PartI 素数判定

    如果现在给你一个数N,你要怎样判断他是否是素数,显然我们可以直接枚举1-sqrt(N)的数能否整除N,如果可以一定是合数

    但这样的时间复杂度很不优秀

    这时就要用到Miller Rabin算法了

     PartII 前置知识---费马小定理和二次探测

    (1):费马小定理:若P是质数,且(a,p)=1,ap-1≡1 (mod P)

      (2): 二次探测:对于素数P,能够满足x2≡1 (mod P)的同余类x只有x≡1 (mod P)和x≡p-1 (mod P)

    PartIII  算法流程(对于N)

    (1):筛掉偶数

    (2):找到一个最大的s使得2s*t=N-1

    (3):随机选取质数a,我们先算出 a^t,然后不断地平方并且进行二次探测(进行 s 次)。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read()
    {
        int f=1,x=0;
        char ch;
        do
        {
            ch=getchar();
            if(ch=='-') f=-1;
        }while(ch<'0'||ch>'9');
        do
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    typedef long long ll;
    
    ll n;
    ll p[12]={2,3,5,7,11,13,17,19,23,29,31,37};
    
    inline ll Pow(ll a,ll b,ll c)
    {
        ll ans=1,mul=a;
        while(b)
        {
            if(b&1)
            {
                ans*=mul;
                ans%=c;    
            }
            mul*=mul;
            mul%=c;
            b>>=1;
        }
        return ans%c;
    }
    
    inline bool Miller_Rabin(ll x)
    {
        if(x==1){
            return false;
        }
        if(x==2) return true;
        if(x%2==0) return false;
        bool f=1;
        for(ll i=0;i<12;i++)
        {
            if(p[i]==x) return true;
            ll t=x-1,s=0;
            while(t%2==0){
                t/=2;
                s++;
            }
            ll cur=Pow(p[i],t,x);
            if(cur==1) continue;
            for(ll j=1;j<=s;j++)
            {
                ll nxt=cur*cur%x;
                if(nxt==1&&cur!=1&&cur!=x-1)
                {
                    f=0;
                    break;
                }
                cur=nxt;
                if(cur==1) break;
            }
            if(cur!=1) f=0;
            if(!f) break;
        }
        return f;
        
    }
    
    int main()
    {
        n=read();
        if(Miller_Rabin(n))
        {
            cout<<"IS PRIME"<<endl;
        } 
        else cout<<"NOT PRIME"<<endl;
    }
  • 相关阅读:
    DEBUG 知识
    转载:telnet启动后的登录问题
    通过ip找主机名
    转载:网线的相关知识
    hdu2717(广度优先搜索)
    hdu1241(bfs)
    hdu1060 数论
    大数除(hdu2117)
    hdu1159(DP)
    hdu2181__DFS
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/11266625.html
Copyright © 2011-2022 走看看