Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

BZOJ 3667: Rabin-Miller算法

Time Limit: 60 Sec  Memory Limit: 512 MB
Submit: 1044  Solved: 322
[Submit][Status][Discuss]

Description

 

Input

第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数。你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 
第二,如果不是质数,输出它最大的质因子是哪个。 

Output

第一行CAS(CAS<=350,代表测试数据的组数) 
以下CAS行:每行一个数字,保证是在64位长整形范围内的正数。 
对于每组测试数据:输出Prime,代表它是质数,或者输出它最大的质因子,代表它是和数 

Sample Input

6
2
13
134
8897
1234567654321
1000000000000

Sample Output

Prime
Prime
67
41
4649
5

HINT

数据范围: 

保证cas<=350,保证所有数字均在64位长整形范围内。 

分析:虽然题目叫做Miller rabin算法,不过真正上也需要Pollard rho算法

  1 /*貌似这个代码在BZOJ上的评测器就会运行错误,但是在POJ上一道原题却通过了(POJ上语言选C++可以过,选择G++就过不了)*/
  2 #include<iostream>
  3 using namespace std;
  4 #include<cstdio>
  5 #define S 10
  6 #include<cstdlib>
  7 #include<ctime>
  8 #define ll long long
  9 ll cas, maxz=-1;
 10 ll read()
 11 {
 12     ll ans=0;char c;
 13     c=getchar();
 14     while(c<'0'||c>'9') c=getchar();
 15     while(c>='0'&&c<='9') 
 16     {
 17         ans=ans*10+c-'0';
 18         c=getchar();
 19     }
 20     return ans;
 21 }
 22 ll quick_mul_mod(ll a,ll b,ll c)//a*b%c
 23 {
 24     ll ret=0;
 25     a%=c;b%=c;
 26     while(b)
 27     {
 28         if(b&1)
 29         {
 30             ret+=a;
 31             ret%=c;
 32             b--;
 33         }
 34         a<<=1;
 35         a%=c;
 36         b>>=1;
 37     }
 38     return ret;
 39 }
 40 ll gcd(ll a,ll b)
 41 {
 42     if(a==0) return 1;
 43     if(a<0) return gcd(-a,b);
 44     if(b==0)
 45     return a;
 46     return gcd(b,a%b);
 47 }
 48 ll Pollard_rho(ll x,ll c)
 49 {
 50     ll x1=rand()%(x-1)+1;
 51     ll x2=x1;
 52     int i=1,k=2;
 53     while(1)
 54     {
 55         i++;
 56         x1=(quick_mul_mod(x1,x1,x)+c)%x;
 57         ll d=gcd(x2-x1,x);
 58         if(d!=1&&d!=x) return d;
 59         if(x2==x1) return x;
 60         if(i==k)
 61         {
 62             x2=x1;
 63             k+=k;
 64         }
 65     }
 66     
 67 }
 68 ll quick_mod(ll a,ll b,ll c)//ji suan a^b%c
 69 {
 70     ll ans=1;
 71     a%=c;
 72     while(b)
 73     {
 74         if(b&1)
 75         {
 76             b--;
 77             ans=quick_mul_mod(ans,a,c);
 78         }
 79         b>>=1;
 80         a=quick_mul_mod(a,a,c);
 81     }
 82     return ans;
 83 }
 84 bool Miller_rabin(ll n)
 85 {
 86     if(n==2) return true;
 87     if(n<=1||!(n&1)) return false;
 88     ll u=n-1,t=0;
 89     while(!(u&1))
 90     {
 91         u>>=1;
 92         t++;
 93     }
 94     for(int i=0;i<S;++i)
 95     {
 96         ll x=rand()%(n-1)+1;
 97         x=quick_mod(x,u,n);
 98         for(int i=1;i<=t;++i)
 99         {
100             ll y=quick_mul_mod(x,x,n);
101             if(y==1&&x!=1&&x!=n-1)
102               return false;
103             x=y;
104         }
105         if(x!=1) return false;
106     }
107     return true;
108 }
109 void findpri(ll n)
110 {
111     if(n==1) return;
112     if(Miller_rabin(n))
113     {
114         maxz=max(maxz,n);
115         return;
116     }
117     ll p=n;
118     while(p==n)
119       p=Pollard_rho(p,rand()%(n-1)+1);
120     findpri(p);
121     findpri(n/p);
122 }
123 int main()
124 {
125     srand(time(0));
126     cas=read();
127     while(cas--)
128     {
129         maxz=0;
130         ll n=read();
131         findpri(n);
132         if(maxz==n)/*最大的质因数就是本身*/
133           printf("Prime
");
134         else printf("%lld
",maxz);
135     }
136     return 0;
137  } 
原文地址:https://www.cnblogs.com/c1299401227/p/5515229.html