Prime Test(POJ 1811)
素数判定的模板题,运用米勒-罗宾素数判定,然后用Pollard_Rho法求出质因数。使用相应的模板即可,不过注意存储质因子的数组需要使用vector,并且使用long long类型存储,不然存储不下,而且输出最下的质因子时,需要写个迭代器进行查询。
完整代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std; typedef long long LL;
vector <LL> fac;
LL gcd(LL a, LL b)
{
return b == ? a : gcd(b, a%b);
} LL mul_mod(LL a, LL x, LL n) ///计算a*x%n,其中t用于存储结果,当t>=n的时候,t对n的模减去n即可(不会出现t>=2*n的情况,因为a也对n取了模)
{
LL t = ;
while(x)
{
if(x & )
{
t += a;
if(t >= n) t -= n;
}
a <<= ;
if(a >= n) a -= n;
x >>= ;
}
return t;
} LL pow2_mod(LL a, LL x, LL n)/// //乘方快速幂
{
LL t = ;
a %= n;
while(x)
{
if(x & ) t = mul_mod(t, a, n);
a = mul_mod(a, a, n);
x >>= ;
}
return t;
}
///不断选取不超过n-1的基b(s次),计算是否每次都有b^(n-1) ≡ 1(mod n),若每次都成立则n是素数,否则为合数。
bool test(LL n, LL a, LL d)///n 为测试数,a为素数表中的数,d为正奇数,这里运用位运算,将n-1不断通过快速幂,同时将n-1向左位移,进行抽出指数中2的操作,从而不断进行素数检测
{
if(n == ) return true;///为2肯定是素数
if(n == a) return true;///如果n等于素数表里面的数则肯定是素数
if((n&) == ) return false;///如果是偶数,则肯定不是素数
while(!(d&)) d >>=;///选取奇数
LL t = pow2_mod(a, d, n);///进行快速幂运算
while((d != n-) && (t != ) && (t != n-))///由二次探测定理可知,只有当t等于1或者n-1时,n才为素数
{
/// t = (LL)t*t%n;
t = mul_mod(t, t, n);
d = d<<;
}
return (t == n- || (d&) == );
} bool isPrime(LL n)
{
///有些题目把1看作质数,但是负数不会是质数
if(n < ) return false;
LL a[] = {, , };
for(int i = ; i <= ; i++) if(!test(n, a[i], n-)) return false;
return true;
} LL Pollard_Rho(LL n, LL c)
{
LL x, y, d;
LL i = , k = ;
x = y = rand() % n;
do
{
i++;
d = gcd(n + y - x, n);
if(d > && d < n) return d;
if(i == k)
{
y = x;
k <<= ;
}
x = (mul_mod(x, x, n) + n - c) % n;
}
while(y != x);
return n;
}
void rhoAll(LL n)
{
if(n <= ) return;
if(isPrime(n))
{
fac.push_back(n);
return;
}
LL t = n;
while(t >= n)
t = Pollard_Rho(n, rand() % (n-) + );
rhoAll(t);
rhoAll(n/t);
return;
} int main()
{
LL n;
int t;
cin>>t;
while(t--)
{
while(cin>>n)
{
if(isPrime(n))
cout<<"Prime"<<endl;
else
{
fac.clear();
rhoAll(n);
LL mins=;
for(vector<LL> ::iterator it=fac.begin();it!=fac.end();++it)
mins=min(mins,*it);
cout<<mins<<endl;
}
}
}
return ;
}
其中米勒-罗宾判断法模板如下:
typedef long long LL;
LL gcd(LL a, LL b)
{
return b == ? a : gcd(b, a%b);
} LL mul_mod(LL a, LL x, LL n) ///计算a*x%n,其中t用于存储结果,当t>=n的时候,t对n的模减去n即可(不会出现t>=2*n的情况,因为a也对n取了模)
{
LL t = ;
while(x)
{
if(x & )
{
t += a;
if(t >= n) t -= n;
}
a <<= ;
if(a >= n) a -= n;
x >>= ;
}
return t;
} LL pow2_mod(LL a, LL x, LL n)/// //乘方快速幂
{
LL t = ;
a %= n;
while(x)
{
if(x & ) t = mul_mod(t, a, n);
a = mul_mod(a, a, n);
x >>= ;
}
return t;
}
///不断选取不超过n-1的基b(s次),计算是否每次都有b^(n-1) ≡ 1(mod n),若每次都成立则n是素数,否则为合数。
bool test(LL n, LL a, LL d)///n 为测试数,a为素数表中的数,d为正奇数,这里运用位运算,将n-1不断通过快速幂,同时将n-1向左位移,进行抽出指数中2的操作,从而不断进行素数检测
{
if(n == ) return true;///为2肯定是素数
if(n == a) return true;///如果n等于素数表里面的数则肯定是素数
if((n&) == ) return false;///如果是偶数,则肯定不是素数
while(!(d&)) d >>=;///选取奇数
LL t = pow2_mod(a, d, n);///进行快速幂运算
while((d != n-) && (t != ) && (t != n-))///由二次探测定理可知,只有当t等于1或者n-1时,n才为素数
{
/// t = (LL)t*t%n;
t = mul_mod(t, t, n);
d = d<<;
}
return (t == n- || (d&) == );
} bool isPrime(LL n)
{
///有些题目把1看作质数,但是负数不会是质数
if(n < ) return false;
LL a[] = {, , };
for(int i = ; i <= ; i++) if(!test(n, a[i], n-)) return false;
return true;
}
Pollard_Rho法求大数的质因子代码模板如下:
vector <LL> fac;
LL Pollard_Rho(LL n, LL c)
{
LL x, y, d;
LL i = , k = ;
x = y = rand() % n;
do
{
i++;
d = gcd(n + y - x, n);
if(d > && d < n) return d;
if(i == k)
{
y = x;
k <<= ;
}
x = (mul_mod(x, x, n) + n - c) % n;
}
while(y != x);
return n;
}
void rhoAll(LL n)
{
if(n <= ) return;
if(isPrime(n))
{
fac.push_back(n);
return;
}
LL t = n;
while(t >= n)
t = Pollard_Rho(n, rand() % (n-) + );
rhoAll(t);
rhoAll(n/t);
return;
}
迭代器书写格式如下:
vector<LL> ::iterator it=fac.begin()///用于遍历vector数组
Prime Test(POJ 1811)的更多相关文章
- 模板题Pollard_Rho大数分解 A - Prime Test POJ - 1811
题意:是素数就输出Prime,不是就输出最小因子. #include <cstdio> #include<time.h> #include <algorithm> ...
- POJ 1811 Prime Test (Rabin-Miller强伪素数测试 和Pollard-rho 因数分解)
题目链接 Description Given a big integer number, you are required to find out whether it's a prime numbe ...
- Miller_rabin算法+Pollard_rho算法 POJ 1811 Prime Test
POJ 1811 Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 32534 Accepted: 8 ...
- 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429
素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: h ...
- Prime Path(POJ - 3126)【BFS+筛素数】
Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...
- 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29046 Accepted: 7342 Case ...
- poj 1811 Prime Test 大数素数测试+大数因子分解
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 27129 Accepted: 6713 Case ...
- Miller&&Pollard POJ 1811 Prime Test
题目传送门 题意:素性测试和大整数分解, N (2 <= N < 254). 分析:没啥好讲的,套个模板,POJ上C++提交 收获:写完这题得到模板 代码: /************** ...
- POJ 1811 Prime Test(Miller-Rabin & Pollard-rho素数测试)
Description Given a big integer number, you are required to find out whether it's a prime number. In ...
随机推荐
- vue 跳外链
var host = window.location.host;var protocal = window.location.protocolwindow.location.href = protoc ...
- matlab plot line settings
- shell脚本学习之参数传递
shell之参数传递 我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 实例 以 ...
- 机器学习---笔记----numpy和math包中的常用函数
本文只是简单罗列一下再机器学习过程中遇到的常用的数学函数. 1. math.fabs(x): 返回x的绝对值.同numpy. >>> import numpy >>> ...
- [leetcode整理]
=======简单 leetcode164 Maximum Gap sort两次 =======有参考 330 Patching Array 98 Validate Binary Search Tre ...
- Linux音频驱动学习之:(1)ASOC分析
一.音频架构概述 (1)ALSA是Advanced Linux Sound Architecture 的缩写,目前已经成为了linux的主流音频体系结构,想了解更多的关于ALSA的这一开源项目的信息和 ...
- 深入理解java虚拟机---对象的创建过程(八)
1.对象的创建过程 由于类的加载是一个很复杂的过程,所以这里暂时略过,后面会详细讲解,默认为是已加载过的类.着重强调对象的创建过程. 注意: 最后一步的init方法是代码块和构造方法. 以上是总图,下 ...
- ssh框架中,工具类调用service层方法(参考https://www.cnblogs.com/l412382979/p/8526945.html)
代码如下: package common.dataService; import javax.annotation.PostConstruct; import org.springframework. ...
- SQL-1 选取表中某一属性最大值的所有信息 查找最晚入职员工的所有信息
题目描述 查找最晚入职员工的所有信息CREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`fi ...
- Docker(2):快速入门及常用命令
什么是Docker? Docker 是世界领先的软件容器平台.开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题.运维人员利用 Docker 可以在隔离容器中并行运行和管理 ...