Prime Test
Time Limit: 6000MS
Memory Limit: 65536K
Total Submissions: 29193
Accepted: 7392
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 < 2^54).

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

Source

POJ Monthly

题目大意:T组数据,对于输入的N,若N为素数,输出"Prime",否则输出N的最小素因子

思路:由于N的规模为2^54所以普通的素性推断果断过不了。

要用Miller Rabin素数測试来做。

而若N不为素数。则须要对N进行素因子分解。由于N为大数,考虑用Pollar Rho整数分解来做。

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<time.h>
  4. #include<math.h>
  5. #define MAX_VAL (pow(2.0,60))
  6. //miller_rabbin素性測试
  7. //__int64 mod_mul(__int64 x,__int64 y,__int64 mo)
  8. //{
  9. // __int64 t;
  10. // x %= mo;
  11. // for(t = 0; y; x = (x<<1)%mo,y>>=1)
  12. // if(y & 1)
  13. // t = (t+x) %mo;
  14. //
  15. // return t;
  16. //}
  17.  
  18. __int64 mod_mul(__int64 x,__int64 y,__int64 mo)
  19. {
  20. __int64 t,T,a,b,c,d,e,f,g,h,v,ans;
  21. T = (__int64)(sqrt(double(mo)+0.5));
  22. t = T*T - mo;
  23. a = x / T;
  24. b = x % T;
  25. c = y / T;
  26. d = y % T;
  27. e = a*c / T;
  28. f = a*c % T;
  29. v = ((a*d+b*c)%mo + e*t) % mo;
  30. g = v / T;
  31. h = v % T;
  32. ans = (((f+g)*t%mo + b*d)% mo + h*T)%mo;
  33. while(ans < 0)
  34. ans += mo;
  35. return ans;
  36. }
  37. __int64 mod_exp(__int64 num,__int64 t,__int64 mo)
  38. {
  39. __int64 ret = 1, temp = num % mo;
  40. for(; t; t >>=1,temp=mod_mul(temp,temp,mo))
  41. if(t & 1)
  42. ret = mod_mul(ret,temp,mo);
  43.  
  44. return ret;
  45. }
  46.  
  47. bool miller_rabbin(__int64 n)
  48. {
  49. if(n == 2)
  50. return true;
  51. if(n < 2 || !(n&1))
  52. return false;
  53. int t = 0;
  54. __int64 a,x,y,u = n-1;
  55. while((u & 1) == 0)
  56. {
  57. t++;
  58. u >>= 1;
  59. }
  60. for(int i = 0; i < 50; i++)
  61. {
  62. a = rand() % (n-1)+1;
  63. x = mod_exp(a,u,n);
  64. for(int j = 0; j < t; j++)
  65. {
  66. y = mod_mul(x,x,n);
  67. if(y == 1 && x != 1 && x != n-1)
  68. return false;
  69. x = y;
  70. }
  71. if(x != 1)
  72. return false;
  73. }
  74. return true;
  75. }
  76. //PollarRho大整数因子分解
  77. __int64 minFactor;
  78. __int64 gcd(__int64 a,__int64 b)
  79. {
  80. if(b == 0)
  81. return a;
  82. return gcd(b, a % b);
  83. }
  84.  
  85. __int64 PollarRho(__int64 n, int c)
  86. {
  87. int i = 1;
  88. srand(time(NULL));
  89. __int64 x = rand() % n;
  90. __int64 y = x;
  91. int k = 2;
  92. while(true)
  93. {
  94. i++;
  95. x = (mod_exp(x,2,n) + c) % n;
  96. __int64 d = gcd(y-x,n);
  97. if(1 < d && d < n)
  98. return d;
  99. if(y == x)
  100. return n;
  101. if(i == k)
  102. {
  103. y = x;
  104. k *= 2;
  105. }
  106. }
  107. }
  108.  
  109. void getSmallest(__int64 n, int c)
  110. {
  111. if(n == 1)
  112. return;
  113. if(miller_rabbin(n))
  114. {
  115. if(n < minFactor)
  116. minFactor = n;
  117. return;
  118. }
  119. __int64 val = n;
  120. while(val == n)
  121. val = PollarRho(n,c--);
  122. getSmallest(val,c);
  123. getSmallest(n/val,c);
  124. }
  125. int main()
  126. {
  127. int T;
  128. __int64 n;
  129. scanf("%d",&T);
  130. while(T--)
  131. {
  132. scanf("%I64d",&n);
  133. minFactor = MAX_VAL;
  134. if(miller_rabbin(n))
  135. printf("Prime\n");
  136. else
  137. {
  138. getSmallest(n,200);
  139. printf("%I64d\n",minFactor);
  140. }
  141. }
  142. return 0;
  143. }

POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】的更多相关文章

  1. POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】

    Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...

  2. HDU1164_Eddy&#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

    Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】

    GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...

  4. Miller Rabin素数检测与Pollard Rho算法

    一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...

  5. Miller-Rabbin 素性测试 和 Pollard_rho整数分解

    今天学习一下Miller-Rabbin  素性测试 和 Pollard_rho整数分解. 两者都是概率算法. Miller_Rabbin素性测试是对简单伪素数pseudoprime测试的改进. (ps ...

  6. Miller Rabin素数检测

    #include<iostream> #include<cstdio> #include<queue> #include<cstring> #inclu ...

  7. HDU 3864 D_num Miller Rabin 质数推断+Pollard Rho大整数分解

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=3864 题意:给出一个数N(1<=N<10^18).假设N仅仅有四个约数.就输出除1外的三个约 ...

  8. POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)

    题意:给出a和b的gcd和lcm,让你求a和b.按升序输出a和b.若有多组满足条件的a和b,那么输出a+b最小的.思路:lcm=a*b/gcd   lcm/gcd=a/gcd*b/gcd 可知a/gc ...

  9. Miller Rabbin素数测试

    步骤 ①先写快速幂取模函数 ②MR算法开始 (1)传入两个参数一个是底数一个是n也就是幂数,如果n是一个合数那么可以判定,这个数一定不是素数 (2)然后开始寻找一个奇数的n去计算,如果最后满足a^d% ...

随机推荐

  1. RSA加密前言

    RSA:非对称加密,近期因为工作需要需要实现了一个RSA加密方案.查阅文档无数,主要是通过看他们代码及其引用他人的代码基本实现了跨平台的RSA方案.现在唯一的缺陷是加解密花费的时间太多,下周会把加解密 ...

  2. Android面向HTTP协议发送get请求

    /** * 採用get请求的方式 * * @param username * @param password * @return null表示求得的路径有问题,text返回请求得到的数据 */ pub ...

  3. Android获取Activity(应用)的执行状态及其它信息

    检測某Activity是否在当前Task的栈顶 public static boolean isTopActivy(String cmdName, Context context) { Activit ...

  4. POJ2828 Buy Tickets 【线段树】+【单点更新】+【逆序】

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 12296   Accepted: 6071 Desc ...

  5. lua的table库中经常使用的函数

    lua提供了一些辅助函数来操作table. 比如,从list中insert和remove元素,对array的元素进行sort.或者concatenate数组中的全部strings.以下就具体地解说这些 ...

  6. 让你提前知道软件开发(22):shell脚本文件操作

    文章1部分 再了解C语言 shell脚本中的文件操作 [文章摘要] 编写shell脚本时,经常会涉及到对文件的操作,比方从文件里读取一行数据.向文件追加一行数据等. 完毕文件读写操作的方法有非常多,了 ...

  7. SimpleWiFi模块评估板

    SimpleWiFi评估套件,发货清单:        1.评估版一块. 2.专用WiFi天线一根. 3.配套电源一个. 单模块 是60元,链接如下: http://item.taobao.com/i ...

  8. poj1269(直线交点)

    传送门:Intersecting Lines 题意:给出N组直线,每组2条直线,求出直线是否相交.如果共线则输出LINE,相交则输入点坐标,否则输出NONE. 分析:模板裸题,直接上模板... #in ...

  9. acdream 1222 Quantization Problem [dp]

    称号:acdream 1222 Quantization Problem 题意:给出一个序列 a ,然后给出一个 n * m 的矩阵,让你从这个矩阵中选出一个序列k,使得sum(abs(ki - ai ...

  10. loj1245(数学)

    传送门:Harmonic Number (II) 题意:求sum=n/1+n/2+n/3+...+n/n.(n<2^31) 分析:在一定的区间内n/i的值是一定的,因此要跳过这段区间来加速求解. ...