Miller_rabin算法+Pollard_rho算法 POJ 1811 Prime Test

POJ 1811 Prime Test

Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 32534   Accepted: 8557
Case Time Limit: 4000MS

Description

Given a big integer number, you are required to find out whether it's a prime number.

Input

The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).

Output

For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.

Sample Input

2
5
10

Sample Output

Prime
2
  1 /*遇上一个题目不同,这个题目是输出最小的质因子*/
  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;
 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         if(n!=0)
115         maxz=min(maxz,n);
116         return;
117     }
118     ll p=n;
119     while(p==n)
120       p=Pollard_rho(p,rand()%(n-1)+1);
121     findpri(p);
122     findpri(n/p);
123 }
124 int main()
125 {
126     srand(time(0));
127     cas=read();
128     while(cas--)
129     {
130         maxz=(1<<31)-1;/*不知道为什么这个赋初值的最大值,只有赋值为小于等于(1<<31)-1才对,我的maxz明明是long long型的啊*/
131         ll n=read();
132         findpri(n);
133         if(Miller_rabin(n))
134           printf("Prime
");
135         else printf("%lld
",maxz);
136     }
137     return 0;
138  } 
原文地址:https://www.cnblogs.com/c1299401227/p/5515239.html