题目链接: http://poj.org/problem?id=1811

题意: 判断一个数 n (2 <= n < 2^54)是否为质数, 是的话输出 "Prime", 否则输出其第一个质因子.

思路: 大数质因子分解, 直接用 pollard_rho (详情参见: http://blog.csdn.net/maxichu/article/details/45459533) 模板即可.

代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. #define ll long long
  4. using namespace std;
  5.  
  6. const int MAXN = 1e2;
  7. const int repeat = ;//repeat为检测次数,判断错误率为4^-repeat,一般8~10就够了
  8.  
  9. ll get_mult(ll a, ll b, ll c){//返回a*b%c
  10. a %= c;
  11. b %= c;
  12. ll ret = ;
  13. while(b){
  14. if(b & ){
  15. ret += a;
  16. if(ret >= c) ret -= c;
  17. }
  18. b >>= ;
  19. a <<= ;
  20. if(a >= c) a -= c;
  21. }
  22. return ret;
  23. }
  24.  
  25. ll get_pow(ll x, ll n, ll mod){//返回x^n%mod
  26. ll ret = ;
  27. x %= mod;
  28. while(n){
  29. if(n & ) ret = get_mult(ret, x, mod);
  30. x = get_mult(x, x, mod);
  31. n >>= ;
  32. }
  33. return ret;
  34. }
  35.  
  36. //通过 a^(n-1) = 1(mod n) 来判断n是否为素数
  37. //n-1 = x*2^t 中间使用二次探测定理
  38. //是合数返回true,不一定是合数返回false
  39. bool cherk(ll a, ll n, ll x, ll t){
  40. ll ret = get_pow(a, x, n);
  41. ll last = ret;
  42. for(int i = ; i <= t; i++){
  43. ret = get_mult(ret, ret, n);
  44. if(ret == && last != && last != n - ) return true;
  45. last = ret;
  46. }
  47. if(ret != ) return true;
  48. return false;
  49. }
  50.  
  51. bool Miller_Rabin(ll n){
  52. if(n < ) return false;
  53. if(n == ) return true;
  54. if(!(n & )) return false;//偶数
  55. ll x = n - , t = ;
  56. while(!(x & )){
  57. x >>= ;
  58. t++;
  59. }
  60. // srand(time(NULL));
  61. for(int i = ; i < repeat; i++){
  62. ll a = rand() % (n - ) + ;
  63. if(cherk(a, n, x, t)) return false;
  64. }
  65. return true;
  66. }
  67.  
  68. ll factor[MAXN];
  69. int tot;//n的质因子个数
  70.  
  71. ll get_gcd(ll a, ll b){
  72. ll tmp;
  73. while(b){
  74. tmp = a;
  75. a = b;
  76. b = tmp % b;
  77. }
  78. return a >= ? a : -a;
  79. }
  80.  
  81. ll pollard_rho(ll x, ll c){//返回x的一个因子
  82. ll i = , k = ;
  83. // srand(time(NULL));
  84. ll x0 = rand() % (x - ) + ;
  85. ll y = x0;
  86. while(){
  87. i++;
  88. x0 = (get_mult(x0, x0, x) + c) % x;
  89. ll d = get_gcd(y - x0, x);
  90. if(d != && d != x) return d;
  91. if(y == x0) return x;
  92. if(i == k){
  93. y = x0;
  94. k += k;
  95. }
  96. }
  97. }
  98.  
  99. void findfac(ll n, int k){//对n质因分解并将结果保存到factor中
  100. if(n == ) return;
  101. if(Miller_Rabin(n)){
  102. factor[tot++] = n;
  103. return;
  104. }
  105. ll p = n;
  106. int c = k;//c防止死循环
  107. while(p >= n){
  108. p = pollard_rho(p, c--);
  109. }
  110. findfac(p, k);
  111. findfac(n / p, k);
  112. }
  113.  
  114. int main(void){
  115. ll n;
  116. int t;
  117. cin >> t;
  118. while(t--){
  119. cin >> n;
  120. if(Miller_Rabin(n)) cout << "Prime" << endl;
  121. else{
  122. tot = ;
  123. findfac(n, );
  124. ll sol = factor[];
  125. for(int i = ; i < tot; i++){
  126. sol = min(sol, factor[i]);
  127. }
  128. cout << sol << endl;
  129. }
  130. }
  131. return ;
  132. }

poj1811(pollard_rho模板)的更多相关文章

  1. POJ-1811-Prime Test(pollard_rho模板,快速找最小素因子)

    题目传送门 sol:Pollard_Rho的模板题,刚看了Pollard_Rho和Miller_Rabin很多原理性的东西看不懂,只是记住了结论勉强能敲代码. Pollard_Rho #include ...

  2. HDU-3864 D_num Miller_Rabin和Pollard_rho

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864 题意:给定一个数n,求n的因子只有四个的情况. Miller_Rabin和Pollard_rho ...

  3. POJ 2429

    思路:a/n*b/n=lcm/gcd 所以这道题就是分解ans.dfs枚举每种素数情况.套Miller_Rabin和pollard_rho模板 //#pragma comment(linker, &q ...

  4. 模板题Pollard_Rho大数分解 A - Prime Test POJ - 1811

    题意:是素数就输出Prime,不是就输出最小因子. #include <cstdio> #include<time.h> #include <algorithm> ...

  5. Pollard_Rho大数分解模板题 pku-2191

    题意:给你一个数n,  定义m=2k-1,   {k|1<=k<=n},并且 k为素数;  当m为合数时,求分解为质因数,输出格式如下:47 * 178481 = 8388607 = ( ...

  6. POJ1811 Prime Test(miller素数判断&&pollar_rho大数分解)

    http://blog.csdn.net/shiyuankongbu/article/details/9202373 发现自己原来的那份模板是有问题的,而且竟然找不出是哪里的问题,所以就用了上面的链接 ...

  7. 【POJ1811】【miller_rabin + pollard rho + 快速乘】Prime Test

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

  8. 【转】大素数判断和素因子分解【miller-rabin和Pollard_rho算法】

    集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646 ...

  9. 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429

    素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: h ...

随机推荐

  1. 关于C#客户端引用C++ dll的问题

    近期在做项目的过程中需要在Winform客户端项目引用由C++编译的DLL,于是对相关的内容进行了一些研究,有几点心得总结如下. 第一步是制作要引用的类库: (1)首先拿到C++的dll,需要注意的是 ...

  2. python第三十二天-----算法

    算法(Algorithm):一个计算过程,解决问题的方法时间复杂度:用来评估算法运行效率的一个东西ps:在日常使用中,请使用sort(),because no zuo no die! 1.冒泡排序:指 ...

  3. 将Windows下磁盘出现黑色为分配区域变成绿色区域

    在windows下不知什么原因, 有一块磁盘空间F盘就变成了黑色为分配区域. 黑色区域无法用来安装双系统, 网上查阅资料后, 找到了如何将他重新变回绿色区域的2个方法(方法二是自己无意操作成功的). ...

  4. [Python]python CGI脚本在apache服务器上运行时出现“Premature end of script headers”错误

    在测试自己的python CGI脚本时, 当html网页中的表单form内容传送到服务器python脚本时, 总是出现Premature end of script headers错误, 网页显示是服 ...

  5. 问题:oracle 字符串转换成日期;结果:[oracle] to_date() 与 to_char() 日期和字符串转换

    to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. to_char(日期,& ...

  6. leetcode377

    public class Solution { private int[] dp; public int CombinationSum4(int[] nums, int target) { dp = ...

  7. LNMP 1.3 测试php解析

    测试解析LNMP的php解析 先打开nginx的配置文件 vim /usr/local/nginx/conf/nginx.conf location ~ \.php$ { root html; fas ...

  8. LookupError: unknown encoding: cp65001解决办法

    一.之前手上做的一个web项目,漏洞频发,服务器用的是菜鸟云服务器,那个应急响应中心不错,想不到乌云倒了,白帽子竟然被阿里系养了,题外话了,首先感谢白帽子提的漏洞,同时也感慨自己安全知识,以及意识的薄 ...

  9. [hdu3949]XOR(线性基求xor第k小)

    题目大意:求xor所有值的第k小,线性基模板题. #include<cstdio> #include<cstring> #include<algorithm> #i ...

  10. [poj3686]The Windy's(费用流)

    题目大意: 解题关键:指派问题,待更. #include<cstdio> #include<cstring> #include<algorithm> #includ ...