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 描述 ...
随机推荐
- bzoj 1704: [Usaco2007 Mar]Face The Right Way 自动转身机【贪心+差分】
首先O(n^3)的贪心很好想,就是枚举k然后从前往后扫,扫到反就翻转区间 然后考虑优化掉翻转区间维,就是搞成差分的形式,在翻转区间的尾部打上标记,再用一个变量维护当前的翻转次数,加到当前状态上来判断是 ...
- poj2096Collecting Bugs(概率期望dp)
Collecting Bugs Time Limit: 10000MS Memory Limit: 64000K Total Submissions: 6400 Accepted: 3128 ...
- echarts-gl 3D柱状图保存为图片,打印
echarts-gl生成的立体柱状图生成图片是平面的,但是需求是3D图并且可以打印,我们的思路是先转成图片,然后再打印,代码如下: 生成3D图 <td>图表分析</td> &l ...
- (数论)51NOD 1079 中国剩余定理
一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % 2 = 1, K % 3 = 2, K % 5 = 3.符合条件的最小的K = 23. Input 第1行:1个数 ...
- 使用JS分页 <span> beta 1.0
<html> <head> <title>分页</title> <style> #titleDiv{ width:500px; backgr ...
- 为 C# 代码生成 API 文档(自译)
原文地址:http://broadcast.oreilly.com/2010/09/build-html-documentation-for-y.html#comments Sandcastle 功能 ...
- pycharm但多行注释快捷键
pycharm中同时注释多行代码快捷键: 代码选中的条件下,同时按住 Ctrl+/,被选中行被注释,再次按下Ctrl+/,注释被取消
- 386 Lexicographical Numbers 字典序排数
给定一个整数 n, 返回从 1 到 n 的字典顺序.例如,给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] .请尽可能的优化算法的时间复杂度和空间复杂度. 输入 ...
- cocos2d-x win7 部署
1. 安装 下载python https://www.python.org/downloads/release/python-279/ 2.从官网下载cocos2d-x http://www.co ...
- C语言常见问题总结
1.多次运行程序 解决方法: 错误原因是,已经编译运行出一个exe,没有关闭此exe,又点击编译运行. 应该将之前运行出的exe关闭,再来运行代码 2.单精度类型和双精度类型如何区分使用... 解决方 ...