素数判定的模板题,运用米勒-罗宾素数判定,然后用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)的更多相关文章

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

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

  2. 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 ...

  3. Miller_rabin算法+Pollard_rho算法 POJ 1811 Prime Test

    POJ 1811 Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 32534   Accepted: 8 ...

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

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

  5. Prime Path(POJ - 3126)【BFS+筛素数】

    Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...

  6. 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case ...

  7. poj 1811 Prime Test 大数素数测试+大数因子分解

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 27129   Accepted: 6713 Case ...

  8. Miller&&Pollard POJ 1811 Prime Test

    题目传送门 题意:素性测试和大整数分解, N (2 <= N < 254). 分析:没啥好讲的,套个模板,POJ上C++提交 收获:写完这题得到模板 代码: /************** ...

  9. 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 ...

随机推荐

  1. 查验身份证 (15 分) 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:

    // test4.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束.// #include "pch.h"#include <ios ...

  2. 通过AssemblyResolve事件打包合并exe和dll文件

    使用WPF开发的安装包,在创建快捷方式的时候,需要用到COM程序集Windows Script Host Object Model,引用COM程序集后,会在debug目录生成Interop.IWshR ...

  3. 逆袭之旅DAY31.XIA.JDBC

    2018-07-31 MySQL package oop_emp.com.neusoft.dao; import java.sql.Connection; import java.sql.Driver ...

  4. laravel使用使用 Php Artisan Tinker 实现模型的增删改查

    tinker命令: php artisan tinker 查阅数据库数据: App\User::count(); App\User::where('username', 'samuel')->f ...

  5. 浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别

    本文以CaffeNet为例: 1. train_val.prototxt  首先,train_val.prototxt文件是网络配置文件.该文件是在训练的时候用的. 2.deploy.prototxt ...

  6. 运算类实现 及 GNU Makefile基本结构

    1.运算类的实现,代码如下:  (1)operator.cpp #include<iostream> #include "operator.h" using names ...

  7. 深入理解java虚拟机---lanmbda表达式简介(三)

    1.lanmbda表达式使用  lanbmda表达式的作用: A: 取代内部类 B;增加对集合的操作,从而增强其性能

  8. api中locale或language字段,传送客户端地域信息,一般为下划线

    在请求新闻的分类信息和新闻内容时,需要在api地址中传入local参数,根据用户地区不同返回不同的新闻和分类. local参数,通过navigator.languages[0]获取, 但是,问题来了: ...

  9. L253 Work and Pleasure

    To be really happy and really safe, one ought to have at least two or three hobbies, and they must a ...

  10. vnode的挂载和更新流程 -- 简介.

    来源 vnode原理 diff图解 <div id="app"> {{someVar}} </div> <script type="text ...