POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】
Memory Limit: 65536K
Accepted: 7392
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整数分解来做。
- #include<stdio.h>
- #include<stdlib.h>
- #include<time.h>
- #include<math.h>
- #define MAX_VAL (pow(2.0,60))
- //miller_rabbin素性測试
- //__int64 mod_mul(__int64 x,__int64 y,__int64 mo)
- //{
- // __int64 t;
- // x %= mo;
- // for(t = 0; y; x = (x<<1)%mo,y>>=1)
- // if(y & 1)
- // t = (t+x) %mo;
- //
- // return t;
- //}
- __int64 mod_mul(__int64 x,__int64 y,__int64 mo)
- {
- __int64 t,T,a,b,c,d,e,f,g,h,v,ans;
- T = (__int64)(sqrt(double(mo)+0.5));
- t = T*T - mo;
- a = x / T;
- b = x % T;
- c = y / T;
- d = y % T;
- e = a*c / T;
- f = a*c % T;
- v = ((a*d+b*c)%mo + e*t) % mo;
- g = v / T;
- h = v % T;
- ans = (((f+g)*t%mo + b*d)% mo + h*T)%mo;
- while(ans < 0)
- ans += mo;
- return ans;
- }
- __int64 mod_exp(__int64 num,__int64 t,__int64 mo)
- {
- __int64 ret = 1, temp = num % mo;
- for(; t; t >>=1,temp=mod_mul(temp,temp,mo))
- if(t & 1)
- ret = mod_mul(ret,temp,mo);
- return ret;
- }
- bool miller_rabbin(__int64 n)
- {
- if(n == 2)
- return true;
- if(n < 2 || !(n&1))
- return false;
- int t = 0;
- __int64 a,x,y,u = n-1;
- while((u & 1) == 0)
- {
- t++;
- u >>= 1;
- }
- for(int i = 0; i < 50; i++)
- {
- a = rand() % (n-1)+1;
- x = mod_exp(a,u,n);
- for(int j = 0; j < t; j++)
- {
- y = mod_mul(x,x,n);
- if(y == 1 && x != 1 && x != n-1)
- return false;
- x = y;
- }
- if(x != 1)
- return false;
- }
- return true;
- }
- //PollarRho大整数因子分解
- __int64 minFactor;
- __int64 gcd(__int64 a,__int64 b)
- {
- if(b == 0)
- return a;
- return gcd(b, a % b);
- }
- __int64 PollarRho(__int64 n, int c)
- {
- int i = 1;
- srand(time(NULL));
- __int64 x = rand() % n;
- __int64 y = x;
- int k = 2;
- while(true)
- {
- i++;
- x = (mod_exp(x,2,n) + c) % n;
- __int64 d = gcd(y-x,n);
- if(1 < d && d < n)
- return d;
- if(y == x)
- return n;
- if(i == k)
- {
- y = x;
- k *= 2;
- }
- }
- }
- void getSmallest(__int64 n, int c)
- {
- if(n == 1)
- return;
- if(miller_rabbin(n))
- {
- if(n < minFactor)
- minFactor = n;
- return;
- }
- __int64 val = n;
- while(val == n)
- val = PollarRho(n,c--);
- getSmallest(val,c);
- getSmallest(n/val,c);
- }
- int main()
- {
- int T;
- __int64 n;
- scanf("%d",&T);
- while(T--)
- {
- scanf("%I64d",&n);
- minFactor = MAX_VAL;
- if(miller_rabbin(n))
- printf("Prime\n");
- else
- {
- getSmallest(n,200);
- printf("%I64d\n",minFactor);
- }
- }
- return 0;
- }
POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】的更多相关文章
- POJ2429_GCD & LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...
- POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...
- HDU1164_Eddy'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 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- Miller Rabin素数检测
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #inclu ...
- 关于素数:求不超过n的素数,素数的判定(Miller Rabin 测试)
关于素数的基本介绍请参考百度百科here和维基百科here的介绍 首先介绍几条关于素数的基本定理: 定理1:如果n不是素数,则n至少有一个( 1, sqrt(n) ]范围内的的因子 定理2:如果n不是 ...
- C语言单元測试
C语言单元測试 对于敏捷开发来说,单元測试不可缺少,对于Java开发来说,JUnit非常好,对于C++开发,也有CPPUnit可供使用,而对于传统的C语言开发,就没有非常好的工具可供使用,能够找到的有 ...
- 与数论的厮守01:素数的测试——Miller Rabin
看一个数是否为质数,我们通常会用那个O(√N)的算法来做,那个算法叫试除法.然而当这个数非常大的时候,这个高增长率的时间复杂度就不够这个数跑了. 为了解决这个问题,我们先来看看费马小定理:若n为素数, ...
- 【数论基础】素数判定和Miller Rabin算法
判断正整数p是否是素数 方法一 朴素的判定
随机推荐
- Python 基本数据类型 (二) - 字符串
str.expandtabs([tabsize]): str类型的expandtabs函数,有一个可选参数tabsize(制表符大小) 详细来说,expandtabs的意思就是,将字符串中的制表符\t ...
- Python 输出命令行进度条
在使用 pip 安装时,你会发现有下载进度条,我们也可以借助开源的第三方库来实现这个功能,在项目输出时增加一些可视化效果. 一个简单易用的第三方库是:progress 作者提供了动图很直观地展现了实现 ...
- Eclipse如何创建模拟器
Eclipse如何创建模拟器下载地址:http://developer.android.com/sdk/index.html#downloadJDK安装包: 1, 打开安卓模拟器控制台(windows ...
- SQL server游标基本结构
简单游标遍历数据: BEGIN DECLARE QZ_cursor CURSOR SCROLL FOR /*创建游标*/ SELECT NAME FROM USERINFO/*要遍历的数据*/ OPE ...
- Web开发细节搜集
App_Data 百度百科: App_Data文件夹应该包含应用程序的本地数据存储.它通常以文件(诸如Microsoft Access或Microsoft SQL Server Express数据库 ...
- JSF框架整理
JSP体系结构: JSF主要优势之一就是它既是Java web 应用程序的用户界面标准又是严格遵循 模型-视图-控制器(MVC)设计模式的框架. 用户界面代码(视图)和应用程序数据和逻辑(模型)的清晰 ...
- BZOJ 3309 DZY Loves Math ——莫比乌斯反演
枚举$d=gcd(i,j)$ 然后大力反演 ——来自Popoqqq的博客. 然后大力讨论后面的函数的意义即可. http://blog.csdn.net/popoqqq/article/details ...
- SPOJ GSS5 Can you answer these queries V ——线段树
[题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ...
- static面试总结
static用法: 静态变量: 静态方法: 静态代码块: 静态内部类: 静态导包. 1.静态变量: private static int a = 0 2.静态方法: public static voi ...
- Gauss 高斯消元
高斯消元…… (裸的暴力) 如果你有一个n元的方程组你会怎么办? Ans:直接用初中的解方程组的方法呀! 没错,直接暴力加减消元.那什么是“高斯消元”?说白了,就是普通的加减消元罢了. 本人再考场上打 ...