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 ...
随机推荐
- 运行网站项目时,有时出现Bad Request,该怎么解决?
有时运行网站项目时,出现Bad Request问题
- 学习笔记-AngularJs(五)
之前的页面太丑了,后来我引入了bootstrap.css,把样式进行修了一番,如下图(一不小心,插入个链接,忽略,http://t.cn/RUbL4rP): (链接:http://www.live08 ...
- laravel框架5.2版本组件包开发
一.包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包也采用了树形目录的存储方式.同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的, ...
- 修改placeholder的值---input-placeholder
input-placeholder .box::input-placeholder 目前所有的浏览器都要加前缀 .box::-webkit-input-placeholder{ color: agba ...
- Jdbc连接Oracle12C集群环境
jdbc.url=jdbc:Oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.31.0. ...
- git-github-TortoiseGit综合使用教程(二)快速入门
:建立版本库 在github网站上创建一个版本库,并复制clone地址. git@github.com:jackadam1981/Flask_Base.git https://github.com/j ...
- JDBC连接数据库:单线程、多线程、批处理插入数据的对比
一.单线程(单条循环)插入50000条记录: 每执行一次就要访问一次数据库 import java.sql.Connection; import java.sql.DriverManager; imp ...
- web service基础知识
Web服务基础 用户访问网站的基本流程 我们每天都会用web客户端上网,浏览器就是一个web客户端,例如谷歌浏览器,以及火狐浏览器等. 当我们输入www.oldboyedu.com/时候,很快就能看到 ...
- python 正则表达式笔记
#!usr/bin/env python3 #-*- coding:utf-8 -*- #正则表达式 #在正则表达式中,如果直接给出字符,就是精确匹配.用\d可以匹配一个数字,\w可以匹配一个字母.数 ...
- python 最小二乘拟合,反卷积,卡方检验
import numpy as np # from enthought.mayavi import mlab ''' ogrid[-1:5:6j,-1:5:6j] [array([[-1. ], [ ...