Miller_Rabin codevs 1702 素数判定2

/*
直接费马小定理
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define ll long long
using namespace std;
ll slow_mul(ll a,ll b,ll c)
{
    ll ans=0;
    a=a%c;b=b%c;
    while(b)
      {
          if(b&1)
            {
                b--;
                ans+=a;
                ans%=c;
          }
        a<<=1;a%=c;b>>=1;
      }
    return ans;
}
ll Mi(ll p,ll a,ll mod)
{
    if(p==0)return 1;
    ll x=Mi(p/2,a,mod)%mod;
    x=slow_mul(x,x,mod);
    if(p%2==1)x=slow_mul(x,a,mod);
    return x;
}
int main()
{
    srand(unsigned(time(0)));
    ll p,d,a;
    cin>>p;
    int falg=0;
    if(p==2)
      {
          printf("Yes");
          return 0;
      }
    if(p==1)
      {
          printf("No");
          return 0;
      }
    for(int i=1;i<=10;i++)
      {
          a=rand()%(p-1)+1;
          d=Mi(p-1,a,p);
          if(d!=1)
          {
            falg=0;
              break;
          }
        else falg=1;
      }
    if(falg==1)printf("Yes");
    else printf("No");
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define ll long long
#define T 10 
using namespace std;
ll slow_mul(ll a,ll b,ll c)//防止爆掉
{
    ll ans=0;
    a=a%c;b=b%c;
    while(b)
      {
          if(b&1)
            {
                b--;ans+=a;
                ans=ans%c;
          }
        a=a<<1;a=a%c;
        b=b>>1;
      }
    return  ans;
}
ll Mi(ll a,ll m,ll n)//快速幂 a^m%n 
{
    if(m==0)return 1;
    ll x=Mi(a,m/2,n)%n;
    x=slow_mul(x,x,n);
    if(m%2==1)x=slow_mul(x,a,n);
    return x;
}
bool Miller_Rabin(ll n)
{  
    if(n<2)return 0;
    if(n==2)return 1;
    if(n%2==0)return 0;
    ll m=n-1,j=0;
    while(m%2==0)//计算m j 使得n-1=m*2^j且j尽量大 
      {
          j++;
          m >>=1;
      }
    srand(unsigned(time(0)));
    for(int i=1;i<=T;i++)//T次测试 
      {
          ll a=rand()%(n-1)+1;
        ll x=Mi(a,m,n);//计算a^m%n 
        ll y; 
        for(int k=1;k<=j;k++)
          {
              y=slow_mul(x,x,n);
            if(y==1&&x!=1&&x!=n-1)return 0;//一定不是素数 
            x=y;
          }
        if(x!=1)return 0;//不符合费马小定理 
      }
    return 1;
}
int main()
{
    ll n;
    cin>>n;
    if(Miller_Rabin(n))printf("Yes
");
    else printf("No
");
}
原文地址:https://www.cnblogs.com/yanlifneg/p/5515458.html