POJ 1811 大整数素数判断 Miller_Rabin
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std; #define ll long long
const int S = ;
ll ans; ll gcd(ll a,ll b){
if(a < ) return gcd(-a , b);
if (b==) return a;
return gcd(b , a%b);
} ll multi_mod(ll a , ll b , ll k) //a*b%k
{
a %= k;
b %= k;
ll ret = ;
//这里因为是长整数,for(i=0->b)循环一个个加太耗时,需要采用这种logn复杂度的方法
while(b){
if(b & ){
ret += a;
ret %= k;
}
a <<= ;
a %= k;
b >>= ;
}
return ret;
} ll pow_mod(ll a, ll b, ll mod) //求(a^b)%mod
{
if(b == ) return a%mod;
int bit[] , t = ;
while(b){
bit[t++] = b&;
b>>=;
}
//类似矩阵快速幂
ll ret = ;
for(int i = t- ; i>= ; i--){
ret = multi_mod(ret , ret , mod);
if(bit[i]) ret = multi_mod(ret , a , mod);
}
return ret;
}
//n = x*2^t , 这里以a为底 , 检验n是否为合数
bool check(ll a , ll n , ll x , ll t)
{
ll ret = pow_mod(a , x , n);
ll last = ret; //last记录上一次的数据,保证最后结果模1时,检查到last不为n-1或1,就表示为合数
for(int i = ; i<=t ; i++){
ret = multi_mod(ret,ret,n);
if(ret == && last!= && last!=n-) return true;
last = ret;
}
//始终无法找到余数为1的结果,则表示n为合数
if(ret!=) return true;
return false;
}
//n为合数返回true
bool miller_rabin(ll n)
{
ll x = n- , t = ;
while((x&) == ){
x>>=;
t++;
}
bool flag = true; //保证最后得到的 x^2 mod p = 1 只有x=1或x=p-1两个解,才满足二次探测,否则有其他解就直接证明不是素数
if(t >= && (x&)){
//miller_robin是一种取随机测试数据的算法,这里S=20,给定20组测试数据,当然数据组数越多,正确率越大
for(int i = ; i<S ; i++){
ll a = rand()%(n-)+;
//二次探测在check中检测
if(check(a,n,x,t)){
flag = true;
break;
}
flag = false;
}
}
if(!flag || n==)
return false;
else return true;
} //长整数利用随机数找到其中一个因子
ll Pollard_rho(ll x,ll c){
ll i=,x0=rand()%x,y=x0,k=;
while (){
i++;
x0=(multi_mod(x0,x0,x)+c)%x;
ll d=gcd(y-x0,x);
if (d!=&& d!=x){
return d;
}
if (y==x0) return x;
if (i==k){
y=x0;
k+=k;
}
}
} //不断利用Pollard_rho递归来查找到n的所有素数因子
void find_factor(ll n)
{
if(!miller_rabin(n)){
ans = min(ans , n);
return;
}
ll p = n;
while(p >= n)
p = Pollard_rho(p , rand() % (n-) + );
find_factor(p);
find_factor(n / p);
} int main()
{
srand(time(NULL));
int T;
scanf("%d" , &T);
while(T--){
ll n;
scanf("%lld" , &n);
bool flag = miller_rabin(n);
if(!flag) printf("Prime\n");
else{
ans = n;
find_factor(n); printf("%lld\n" , ans);
}
}
return ;
}
POJ 1811 大整数素数判断 Miller_Rabin的更多相关文章
- POJ 1811 大素数判断
数据范围很大,用米勒罗宾测试和Pollard_Rho法可以分解大数. 模板在代码中 O.O #include <iostream> #include <cstdio> #inc ...
- POJ 1503 大整数
之前做的大整数,都是一位一位操作. 优化方案:压缩方案. 模板: + - * 操作符重载 #include<cstdio> #include<iostream> #inclu ...
- POJ 1811 Prime Test
题意:对于一个大整数,判断是否质数,如果不是质数输出最小质因子. 解法:判断质数使用Miller-Rabin测试,分解质因子使用Pollard-Rho,Miller-Rabin测试用的红书模板,将测试 ...
- 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429
素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: h ...
- POJ 1811 Prime Test (Pollard rho 大整数分解)
题意:给出一个N,若N为素数,输出Prime.若为合数,输出最小的素因子.思路:Pollard rho大整数分解,模板题 #include <iostream> #include < ...
- 【转】大素数判断和素因子分解【miller-rabin和Pollard_rho算法】
集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646 ...
- POJ 1811 Prime Test( Pollard-rho整数分解经典题 )
链接:传送门 题意:输入 n ,判断 n 是否为素数,如果是合数输出 n 的最素因子 思路:Pollard-rho经典题 /************************************** ...
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
- POJ C++程序设计 编程题#1 大整数的加减乘除
编程题#4:大整数的加减乘除 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 ...
随机推荐
- P3469 [POI2008]BLO-Blockade(Tarjan 割点)
P3469 [POI2008]BLO-Blockade 题意翻译 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每 ...
- redis在linux的安装和开机启动(二)
编译 安装 makefile已经存在 执行make 即可 make之后, 自动创建可运行的脚本文件, 不需要再执行 install了. 将脚本文件, 拷贝到指定位置, 就可以了. 手动创建目录, 需要 ...
- Linux安装PHP环境
简介: PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要 ...
- java io 文件下载
/** * 文件下载 * @param response * @param downloadPath * @param docName */ public void downLoadFile( Htt ...
- 394 Decode String 字符串解码
给定一个经过编码的字符串,返回它解码后的字符串.编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正整数.你可以认 ...
- 了解Selenium与自动化测试第一天“云里雾里”
以前没有搭建过Selenium自动化功能测试环境,想象中就像QTP一样,集成IDE一般简单快捷. 昨天通过博客园的一篇博友日志,才开始大概认识到Selenium的工作方式与特征: 1.插件般与浏览器结 ...
- JavaScript开发心得--如何传递某行数据给下一页
1, 应用场景 在某个html页面显示一批数据,如20个用户的名称.年龄等,每行都要一个编辑按钮,点击编辑后,将此行数据带入某个专门的编辑页进行显示,修改后保存. 问题是 点击编辑按钮后,如何得知要编 ...
- 可滚动的ResultSet类型 实现分页
可滚动的ResultSet类型. 这个类型支持前后滚动取得纪录next().previous(),回到第一行first(),同时还支持要取的 ResultSet中的第几行 absolute(int n ...
- sql server nullif的使用技巧,除数为零的处理技巧
在sql server中做除法处理的时候,我们经常需要处理除数为零的情况,因为如果遇到这种情况的时候,sqlserver会抛出遇到以零作除数错误的异常,我们总不希望把这个异常显示给用户吧. 做个会报这 ...
- poi导出word时设置兼容性
接上一篇poi导出word http://www.cnblogs.com/xiufengd/p/4708680.html. public static void setAuto(XWPFDocumen ...