BZOJ3667:Rabin-Miller算法(Pollard-Rho)

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

Solution

传送门

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define LL long long
 6 using namespace std;
 7 
 8 LL T,maxn,x;
 9 LL prime[10]={2,3,5,7,11,13,17,19,23};
10 
11 LL Mul(LL a,LL b,LL MOD)
12 {
13     LL tmp=a*b-(LL)((long double)a*b/MOD+0.1)*MOD;
14     return tmp<0?tmp+MOD:tmp;
15 }
16 
17 LL Qpow(LL a,LL b,LL MOD)
18 {
19     LL ans=1;
20     while (b)
21     {
22         if (b&1) ans=Mul(ans,a,MOD);
23         a=Mul(a,a,MOD); b>>=1;
24     }
25     return ans;
26 }
27 
28 LL gcd(LL a,LL b) {return b==0?a:gcd(b,a%b);}
29 
30 bool Miller_Rabin(LL n)
31 {
32     if (n==2) return 1;
33     if (n<2 || n%2==0) return 0;
34     LL m=n-1, l=0;
35     while (m%2==0) ++l, m>>=1;
36     for (int i=0; i<9; ++i)
37     {
38         LL p=prime[i], w=Qpow(p,m,n);
39         if (w==1 || w==n-1 || p==n) continue;
40         for (int j=1; j<=l; ++j)
41         {
42             LL u=Mul(w,w,n);
43             if (u==1 && w!=1 && w!=n-1) return 0;
44             w=u;
45         }
46         if (w!=1) return 0;
47     }
48     return 1;
49 }
50 
51 LL Pollard_Rho(LL n,LL c)
52 {
53     LL x=rand()%n,y=x,p=1,k=2;
54     for (LL i=1; p==1; ++i)
55     {
56         x=(Mul(x,x,n)+c)%n;
57         p=x>y?x-y:y-x;
58         p=gcd(p,n);
59         if (i==k) y=x,k+=k;
60     }
61     return p;
62 }
63 
64 void Solve(LL n)
65 {
66     if (n==1) return;
67     if (Miller_Rabin(n)) {maxn=max(maxn,n); return;}
68     LL t=n;
69     while (t==n) t=Pollard_Rho(n,rand()%(n-1)+1);
70     Solve(t); Solve(n/t);
71 }
72 
73 int main()
74 {
75     scanf("%lld",&T);
76     while (T--)
77     {
78         scanf("%lld",&x);
79         maxn=0;
80         Solve(x);
81         if (maxn==x) puts("Prime");
82         else printf("%lld\n",maxn);
83     }
84 }

转载于:https://www.cnblogs.com/refun/p/10113979.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值