一个milller_rabin模板

#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
#include <iomanip>

#include <ctime>
#define ll long long
using namespace std;
ll mod_mul(ll a,ll b,ll n){
    ll res=0;
    while(b){
        if(b&1)res=(res+a)%n;
        a=(a+a)%n;
        b>>=1;
    }
    return res;
}
ll mod_exp(ll a,ll b,ll n){
    ll res=1;
    while(b){
        if(b&1)res=mod_mul(res,a,n);
        a=mod_mul(a,a,n);
        b>>=1;
    }
    return res;
}
bool miller_rabin(ll n){
    if(n==2||n==3||n==5||n==7||n==11)return true;
    if(n==1||!(n%2)||!(n%3)||!(n%5)||!(n%7)||!(n%11))return false;
    ll x,pre,u;
    int i,j,k=0;
    u=n-1;
    while(!(u&1)){
        k++;u>>=1;
    }
    srand((ll)time(0));
    for(i=0;i<5;i++){//5次足够AC了
        x=rand()%(n-2)+2;
        if((x%n)==0)continue;
        x=mod_exp(x,u,n);
        pre=x;
        for(j=0;j<k;j++){
            x=mod_mul(x,x,n);
            if(x==1&&pre!=1&&pre!=n-1)return false;
            pre=x;
        }
        if(x!=1)return false;
    }
    return true;
}
int main(){
    ll n;
    while(cin>>n){
        if(miller_rabin(n))puts("is prime");
        else puts("is not prime");
    }
    return 0;
}

代码使用了费马小定理和二次探测定理。详见下面的源博客:

https://www.cnblogs.com/vongang/archive/2012/03/15/2398626.html

原文地址:https://www.cnblogs.com/linruier/p/10596579.html