码迷,mamicode.com
首页 > 编程语言 > 详细

bzoj3667: Rabin-Miller算法

时间:2016-05-08 23:47:18      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:

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位长整形范围内。

 

Source

题解:

这是miller rabin和pollard rho的裸题,具体见:http://blog.csdn.net/thy_asdf/article/details/51347390

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define lowbit(x) ((x)&(-(x)))
 7 using namespace std;
 8 typedef long long int64;
 9 char ch;
10 bool ok;
11 void read(int &x){
12     ok=0;
13     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch==-) ok=1;
14     for (x=0;isdigit(ch);x=x*10+ch-0,ch=getchar());
15     if (ok) x=-x;
16 }
17 void read(int64 &x){
18     ok=0;
19     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch==-) ok=1;
20     for (x=0;isdigit(ch);x=x*10+ch-0,ch=getchar());
21     if (ok) x=-x;
22 }
23 int cases;
24 int64 n;
25 const int prime[10]={2,3,5,7,11,13,17,19,23,29};
26 int64 mul(int64 a,int64 b,int64 mod){
27     int64 d=((long double)a/mod*b+1E-8);
28     int64 res=a*b-d*mod;
29     if (res<0) res+=mod;
30     return res;
31     /*int64 t;
32     for (t=0;b;b>>=1,a<<=1,a%=mod) if (b&1) t=(t+a)%mod;
33     return t;*/
34 }
35 int64 ksm(int64 a,int64 b,int64 mod){
36     int64 t;
37     for (t=1;b;b>>=1,a=mul(a,a,mod)) if (b&1) t=mul(t,a,mod);
38     return t;    
39 }
40 bool miller_rabin(int64 n){
41     for (int i=0;i<10;i++) if (n==prime[i]) return true;
42     if (!(n&1)) return false;
43     int64 bit=lowbit(n-1),s=0,d;
44     while (bit!=1) s++,bit>>=1;
45     d=(n-1)>>s;
46     for (int i=0;i<10;i++){
47         int64 x=ksm(prime[i],d,n);
48         for (int j=1;j<=s;j++){
49             int64 xx=mul(x,x,n);
50             if (xx==1&&x!=n-1&&x!=1) return false;
51             x=xx;
52         }
53         if (x!=1) return false;
54     }
55     return true;
56 }
57 int cnt;
58 int64 list[50];
59 int64 random(int64 lim){return ((1LL*rand()<<31)+rand())%lim;}
60 int64 f(int64 x,int64 mod,int64 c){return (mul(x,x,mod)+c+mod)%mod;}
61 int64 pollard_rho(int64 n,int64 c){
62     int64 x,y,d=1; x=random(n),y=f(x,n,c);
63     while (d==1){
64         d=__gcd(abs(x-y),n);
65         x=f(x,n,c),y=f(f(y,n,c),n,c);
66     }
67     return d;
68 }
69 void work(int64 n){
70     if (miller_rabin(n)){list[++cnt]=n;return;}
71     int64 d=pollard_rho(n,random(n-1));
72     while (d==n||d==1) d=pollard_rho(n,random(n));
73     work(d),work(n/d);
74 }
75 void decompose(int64 n){
76     cnt=0,work(n),sort(list+1,list+cnt+1);
77     printf("%lld\n",list[cnt]);
78 }
79 int main(){
80     srand(19990617);
81     for (read(cases);cases;cases--){
82         read(n);
83         if (miller_rabin(n)) puts("Prime");
84         else decompose(n);
85     }
86     return 0;
87 }

 

bzoj3667: Rabin-Miller算法

标签:

原文地址:http://www.cnblogs.com/chenyushuo/p/5472155.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!