Miller&&Pollard POJ 1811 Prime Test

题目传送门

题意:素性测试和大整数分解, N (2 <= N < 254)。

分析:没啥好讲的,套个模板,POJ上C++提交

收获:写完这题得到模板

代码:

/************************************************
* Author        :Running_Time
* Created Time  :2015-8-28 13:02:38
* File Name     :POJ_1811.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int S = 20;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

/*
	素性测试,Miller_Rabin 随机算法
	可以判断< 2^63的数
	素数:true,合数:false
*/
const int S = 20;									//随机算法判定次数,S越大,判错概率越小

//非递归写法,递归写法可能会爆栈
ll GCD(ll a, ll b)	{
	if (a == 0)	return 1;
	if (a < 0)	a = -a;
	while (b)	{
		ll c = a % b;
		a = b; b = c;
	}
	return a;
}

//计算 (a * b) % p,a,b是long long数,直接相乘可能会溢出
ll multi_mod(ll a, ll b, ll p)	{
	ll ret = 0;
	a %= p;	b %= p;
	while (b)	{
		if (b & 1)	{
			ret += a;
			if (ret >= p)	ret -= p;
		}
		a <<= 1;
		if (a >= p)	a -= p;
		b >>= 1;
	}
	return ret;
}

//计算 a ^ x % p
ll pow_mod(ll a, ll x, ll p)	{
	ll ret = 1;
	a %= p;
	while (x)	{
		if (x & 1)	ret = multi_mod (ret, a, p);
		a = multi_mod (a, a, p);
		x >>= 1;
	}
	return ret;
}

/*
	以a为基,n-1=x*2^t,a^(n-1) = 1(mod n)  验证n是不是合数
	一定是合数返回true, 不一定返回false
*/
bool check(ll a, ll n, ll x, int t)	{
	ll ret = pow_mod (a, x, n);
	ll last = ret;
	for (int i=1; i<=t; ++i)	{
		ret = multi_mod (ret, ret, n);
		if (ret == 1 && last != 1 && last != n - 1)	return true;	//合数
		last = ret;
	}
	if (ret != 1)	return true;
	return false;
}

bool Miller_Rabin(ll n)	{
	if (n == 2)	return true;
	if (n < 2 || ! (n & 1))	return false;			//偶数或1
	ll x = n - 1;	int t = 0;
	while (! (x & 1))	{
		x >>= 1;	t++;
	}
	for (int i=1; i<=S; ++i)	{
		ll a = rand () % (n - 1) + 1;				//需要cstdlib头文件
		if (check (a, n, x, t))	return false;		//合数
	}
	return true;
}

/*
	大整数分解,Pollard_rho 随机算法
	factorize ()保存质因数在vector
*/
ll Pollard_rho(ll x, ll c)	{
	ll i = 1, k = 2;
	ll a = rand () % x;
	ll b = a;
	while (1)	{
		i++;
		a = (multi_mod (a, a, x) + c) % x;
		ll d = GCD (b - a, x);
		if (d != 1 && d != x)	return d;
		if (b == a)	return x;
		if (i == k)	b = a, k += k;
	}
}

void factorize(ll n, vector<ll> &ret)	{
	if (Miller_Rabin (n))	{						//素数
		ret.push_back (n);	return ;
	}
	ll p = n;
	while (p >= n)	p = Pollard_rho (p, rand () % (n - 1) + 1);
	factorize (p, ret);
	factorize (n / p, ret);
}

int main(void)    {
	srand (time (NULL));
	int T;	scanf ("%d", &T);
	while (T--)	{
		ll n;	scanf ("%I64d", &n);
		if (Miller_Rabin (n))	puts ("Prime");
		else	{
			if (n <= 1)	{
				puts ("-1");	continue;
			}
			vector<ll> ans;
			factorize (n, ans);
			sort (ans.begin (), ans.end ());
			printf ("%I64d\n", ans[0]);
			// for (int i=0; i<ans.size (); ++i)	{
			// 	printf ("%I64d%c", ans[i], (i == ans.size ()-1) ? ‘\n‘ : ‘ ‘);
			// }
		}
	}

    return 0;
}

  

时间: 2024-10-29 22:12:29

Miller&&Pollard POJ 1811 Prime Test的相关文章

POJ 1811 Prime Test(费马小定理+二次探测定理)

素数的测试: 费尔马小定理:如果p是一个素数,且0<a<p,则a^(p-1)%p=1. 利用费尔马小定理,对于给定的整数n,可以设计素数判定算法,通过 计算d=a^(n-1)%n来判断n的素性,当d!=1时,n肯定不是素数,当d=1时,n   很可能是素数. 二次探测定理:如果n是一个素数,且0<x<p,则方程x^2%p=1的解为:x=1或    x=p-1. 利用二次探测定理,可以再利用费尔马小定理计算a^(n-1)%n的过程 中增加对整数n的二次探测,一旦发现违背二次探测条件,

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

Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the

poj 1811: Prime Test

题目链接 涉及到大数的素性判定及大数的质因数分解,感觉用处不大.当成一块模板好了 #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; #define abs(a) (a)>=

Prime Test POJ - 1811(素性检测+大数分解)

Prime Test POJ - 1811 题意:判断N (2 <= N < 2 54) 是不是素数,如果不是求它的最小素因数. millerRabin素性检测 + pollard rho大数分解 链接 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 #define LL l

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

素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: http://blog.csdn.net/maxichu/article/details/45459533 然后是参考了kuangbin的模板: http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646396.html 模板如下: //快速乘 (a

poj 1811, poj 2429 (pollard_rho算法)

poj 1811 题意: 给出一个整数n,判断n是不是素数,如果不是素数,输出最小的质因子. 限制: 2 <= N < 2^54 思路: miller_rabin算法判素数 pollard_rho算法求质因子 复杂度O(log(n)) poj 2429 题意: 给出两个数的lcm和gcd,求这两个数. 限制: 0 < lcm,gcd < 2^63 思路: pollard_rho O(log(n))分解质因数. 可以考虑到2^63不同的质因数只有20左右个,而相同的质数不可能分在不同

POJ 1365 Prime Land

Prime Land Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2972 Accepted: 1362 Description Everybody in the Prime Land is using a prime base number system. In this system, each positive integer x is represented as follows: Let {pi}i=0,1,2,

双向广搜 POJ 3126 Prime Path

POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted: 9153 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change th

POJ 3126 Prime Path(素数路径)

p.MsoNormal { margin-bottom: 10.0000pt; font-family: Tahoma; font-size: 11.0000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 24.0000pt } span.10 { font-family: "Times New Rom