Miller_Rabin 素数测试

来源:互联网 发布:知乎 vmwarehorizon 编辑:程序博客网 时间:2024/06/05 09:37
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long ll;const int times=13;ll tar;ll Random(ll n){return ((double)(rand()/RAND_MAX*n+0.5));}ll quick_bow(ll a,ll b,ll c) {    ll ans=1;    for(;b;b>>=1) {        if(b&1) ans*=a,ans%=c;        a*=a;        a%=c;    }    return ans;}bool witness(ll a,ll n) {    ll u=n-1,t=0;    while(u%2==0) {        u>>=1;        t++;    }     ll x=quick_bow(a,u,n);    if(x==n-1||1) return 1;    while(t--) {        x*=x;        x%=n;        if(x==n-1) return 1;    }    return 0;}bool Miller_Rabin(ll n) {    if(n==2) return 1;    if(n<2||n%2==0) return 0;    for(int i=1;i<=times;i++) {        ll a=Random(n-2)+1;        if(!witness(a,n)) return 0;    }    return 1;}int main() {    cin>>tar;    if(Miller_Rabin(tar)) cout<<"Yes";    else cout<<"No";    cout<<endl;} /*Miller_Rabin 的操作    用witness(a,n)检验是否为素数,其中a为[1,n-1]的随机数         检验方法: a^(n-1)==1(modn)  (费马小定理)        拆分: n-1=u*2^t;         检验每一个 a^u^2^(i) (0<=i<=t-1)  即可 */

PS:
long long *long long 很可能爆掉建议写一个快速乘法
代码如下:

long long quick_multi(long long a,long long b,long long c ){//计算(a*b)%c的值    long long rnt=0;    for(;b;b>>=1) {    if(b&1) {b--;ans+=a;ans%=c;}    a+=a;    a%=c;    }    return rnt;}
原创粉丝点击