目录
1.Miller_Rabin
1.1Miller_Rabin介绍
Miller_Rabin是基于概率的大素数检测算法
1.2算法原理
定理一:若 为素数,那么有 (费马小定理)
定理二:若 为素数,且 成立,那么 (二次探测定理)
以上定理的证明过程,不再赘述
Miller_Rabin算法的原理是由以上两个定理经过一系列的推导得出的:
具体推导过程,我给出以下的参考网站:
https://blog.csdn.net/ECNU_LZJ/article/details/72675595
1.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时间复杂度
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;
}
}