Miller_Rabin和Pallard_Rho(基于概率的大素数检测和大整数的因式分解)

目录

1.Miller_Rabin

1.1Miller_Rabin介绍

1.2算法原理

1.3时间复杂度

1.4code

2.Pallard_Rho

2.1Pallard_Rho介绍

2.2算法原理

2.3时间复杂度

2.4code

3.参考文档


1.Miller_Rabin

1.1Miller_Rabin介绍

Miller_Rabin是基于概率的大素数检测算法

1.2算法原理

定理一:若 p 为素数,那么有  a^{p-1}\equiv 1 \ mod \ p (费马小定理)

定理二:若 p 为素数,且  x^2 \equiv 1 \ mod \ p  成立,那么  x = 1 \ or \ x=p-1(二次探测定理)

以上定理的证明过程,不再赘述

Miller_Rabin算法的原理是由以上两个定理经过一系列的推导得出的:
具体推导过程,我给出以下的参考网站:
https://blog.csdn.net/ECNU_LZJ/article/details/72675595

1.3时间复杂度

时间复杂度约为\bg_white O(k \cdot logn^3)

1.4code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll quick_multi(ll a,ll b,ll c)//速度太慢的话,可以去掉
{
	ll ans=0;
	while(b)
	{
		if(b&1)	ans=(ans+a)%c;
		a=(a+a)%c;
		b>>=1;
	}
	return ans;
}
ll quick_mod(ll a,ll b,ll c)
{
	ll ans=1;
	while(b)
	{
		if(b&1)	ans=quick_multi(ans,a,c);
		a=quick_multi(a,a,c);
		b>>=1;
	}
	return ans;
}
bool mr0(ll x,ll p)
{
	if(quick_mod(x,p-1,p)!=1)
		return false;
	ll k = p-1;
	while (k % 2 == 0)
	{
		k>>=1;
		ll t=quick_mod(x,k,p);
		if(t != 1&& t != p - 1)
			return false;
		if(t == p - 1)
			return true;
	}
	return true;
}
bool mr(ll p)
{
	if(p == 2 || p == 3 || p == 5 || p == 7)
		return true;
	return mr0(2, p) && mr0(3, p) && mr0(5, p) && mr0(7, p);
}
int main()
{
	ll p;//p!=1
	while(cin>>p)
	{
		if(mr(p))	cout<<"prime\n";
		else cout<<"not prime\n";
	}
}

 

2.Pallard_Rho

2.1Pallard_Rho介绍

Pallard_Rho是用来做大整数的因式分解的有力武器,考虑到尝除法或者一般的线性筛法,在n>=1e7时无法承受,因此借助Pallard_Rho+Miller_Rabin可以快速分解大整数

2.2算法原理

利用Floyd环,其他我就不知道了(玄学算法。。。)

2.3时间复杂度

O(n^{\frac{1}{4}})

2.4code

#include<bits/stdc++.h>
const int Times = 10;
const int N = 5500;
using namespace std;
typedef long long ll;
ll ct,cnt;
ll fact[N],num[N];

ll gcd(ll a,ll b)	{return b==0?a:gcd(b,a%b);}
ll quick_multi(ll a,ll b,ll c)	//速度太慢的话,可以去掉
{
	ll ans=0;
	while(b)
	{
		if(b&1)	ans=(ans+a)%c;
		a=(a+a)%c;
		b>>=1;
	}
	return ans;
}
ll quick_mod(ll a,ll b,ll c)
{
	ll ans=1;
	while(b)
	{
		if(b&1)	ans=quick_multi(ans,a,c);
		a=quick_multi(a,a,c);
		b>>=1;
	}
	return ans;
}
bool mr0(ll x,ll p)
{
	if(quick_mod(x,p-1,p)!=1)
		return false;
	ll k = p-1;
	while (k % 2 == 0)
	{
		k>>=1;
		ll t=quick_mod(x,k,p);
		if(t != 1&& t != p - 1)
			return false;
		if(t == p - 1)
			return true;
	}
	return true;
}
bool mr(ll p)
{
	if(p == 2 || p == 3 || p == 5 || p == 7)
		return true;
	return mr0(2, p) && mr0(3, p) && mr0(5, p) && mr0(7, p);
}
ll pollard_rho(ll n,ll c)
{
	ll i=1,k=2;
	ll x=rand()%(n-1)+1;
	ll y=x;
	while(1)
	{
		++i;
		x=(quick_multi(x,x,x)+c)%n;
		ll d=gcd((y-x+n)%n,n);
		if(1<d&&d<n)	return d;
		if(y == x)	return n;
		if(i == k)
		{
			y=x;
			k <<= 1;
		}
	}
}
void find(ll n,int c)
{
	if(n==1)	return;
	if(mr(n))
	{
		fact[ct++]=n;
		return;
	}
	ll p=n;
	ll k=c;
	while(p>=n)	p=pollard_rho(p,c--);
	find(p,k);
	find(n/p,k);
}
int main()
{
	ll n;
	while(cin>>n)
	{
		ct=0;
		find(n,120);
		sort(fact,fact+ct);
		num[0]=1;
		int k=1;
		for(int i=1;i<ct;++i)
		{
			if(fact[i] == fact[i-1])
				++num[k-1];
			else
			{
				num[k]=1;
				fact[k++]=fact[i];
			}
		}
		cnt=k;
		for(int i=0;i<cnt;++i)
			cout<<fact[i]<<'^'<<num[i]<<' ';
		cout<<endl;
	}
}

 

3.参考文档

1.https://www.cnblogs.com/dalt/p/8436883.html

2.https://blog.csdn.net/ECNU_LZJ/article/details/72675595

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值