[模板] Miller_Rabin素数判断代码实现存档

就是....存存代码吧。
Miller_Rabin的最核心部分在于二次探测定理和费马小定理。后者在同余/逆元的题目里面或多或少都有提及吧.....前者也很简单。
总而言之,Miller_Rabin不算很难啦,值得去学习一下~

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int S=5;
ll qpow(ll x,ll k,ll mod){
    ll ret=1;
    while(k){
        if(k&1) ret=(ret*x)%mod;
        x=(x*x)%mod;
        k>>=1;
    }
    return ret;
}

bool miller_rabin(ll n){
    if(n<2) return false;
    if(n==2) return true; // 特判一波
    ll x,pre,u;
    int k=0;
    u=n-1;
    while(!(u&1)){
        k++, u>>=1;
    } // 取2位数
    for(int i=1;i<S;i++){ // 做S次判断
        x=rand()%(n-2)+2; // 随机取(2,n)的数,n若是质数,x肯定与n互质
        x=qpow(x,u,n); // 先算 x^u
        pre=x;
        for(int i=0;i<k;i++){
            x=(x*x)%n; // x^2,二次探测定理
            if(x==1 && pre!=1 && pre!=n-1) return false;
            pre=x;
        }
        if(x%n!=1)return false; // 费马小定理
    }
    return true;
}

int main(){
    ios::sync_with_stdio(false);
    srand(time(0));
    int m,na;
    cin>>m>>m;
    while(m--){
        cin>>na;
        if(miller_rabin(na)) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}
posted @ 2017-11-09 08:12 ajcxsu 阅读(...) 评论(...) 编辑 收藏