目录
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.参考文档
Miller_Rabin是基于概率的大素数检测算法
定理一:若 为素数,那么有 (费马小定理)
定理二:若 为素数,且 成立,那么 (二次探测定理)
以上定理的证明过程,不再赘述
Miller_Rabin算法的原理是由以上两个定理经过一系列的推导得出的:
具体推导过程,我给出以下的参考网站:
https://blog.csdn.net/ECNU_LZJ/article/details/72675595
时间复杂度约为
#include
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";
}
}
Pallard_Rho是用来做大整数的因式分解的有力武器,考虑到尝除法或者一般的线性筛法,在n>=1e7时无法承受,因此借助Pallard_Rho+Miller_Rabin可以快速分解大整数
利用Floyd环,其他我就不知道了(玄学算法。。。)
#include
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=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
1.https://www.cnblogs.com/dalt/p/8436883.html
2.https://blog.csdn.net/ECNU_LZJ/article/details/72675595