- クイック&高速電力乗ります
- フェルマーの小定理
- 定理二次プローブ
- pollorロー
- ミラー上昇
導入にポラードのロー乗算の多数等月長い長いバーストためのアルゴリズムの前に、迅速な乗算および迅速電力を普及します。
#include<cstdio>
#include<iostream>
using namespace std;
long long p,n;
int mul(long b,long a)//快速乘
{
long long ret=0;
while(b)
{
if(b&1)
{
ret=(ret+a)%p;
}
b>>=1;
a=(a+a)%p;
}
return ret;
}
int pow(long long a,long long n)//快速幂
{
long long ret=1;
while(n)
{
if(n&1)
{
ret=mul(ret,a);
}
n>>=1;
a=mul(a,a);
}
return ret;
}
int main()
{
while(scanf("%I64d%I64d",&n,&p))
{
printf("%I64d",pow(2,n)%p);
}
}
フェルマーの小定理
pは素数、およびGCD(P)= 1である場合 、 次に^(P-1)≡1 (MOD P)。
つまり整数である場合、pは素数、及び、Pプライム(両方とも1の、即ち、唯一の除数)であり、次いで、(P-1)番目の電力を一定の剰余分割後のpによっては1に等しいです。
証明します
補題1。
A、B、Cは任意の整数3である場合、mは正の整数であり、(M、C)= 1、次いでac≡bc(modm)、そこa≡b(modm)であります
証明:ac≡bcは(MOD M)(M、C)= 1、すなわち、M、C互いに素、cは約あることができるので、(AB)c≡0(MOD m)を得ることができるAC-bc≡0(MOD m)を求めることができます、A-b≡0(MOD M)にa≡bを得ることができる(MOD M)
補題2。
mは整数とすると、M> 1は、A1、A2、A3、A4の場合、Bは整数であり、(M、B)= 1である、 ... AMは、完全に残りの行は、Mを法であり、BA [1] BA [2]、BA [3 ]、BA [4]、... BA [m]はモジュロMの完全残留システムを構成しています。
証明:2つの整数とBAのBA [J]合同が存在する場合、すなわちba≡ba[j]は、補題1はa≡a[J](MOD M)完全に残りのシステムに従って定義されている(MOD M)。これが不可能であるため、二つの整数のBAのBA [J]がBA [1]、BA [2]、BA [3]、BA [4]、... BA [m]は、金型を構成するように、合同存在しないことを見出しました完全Mの残りの行。
残り完全に構成されたシステム素数p
{1,2,3,4 ...、P-1}
GCD(P)== 1ため 、 補助定理2から市販
{、2A、3A、4A 、5A ... ···(P-1)}も完全残基システムです。
システムが利用できる完全に残っている特性を有する1 * 2 * 3 * 4 * 5 ... .. *(P-1)== * 2A * 3A * 4A * 5A ......(P-1)%のP、
そう( !! P-1)≡( P-1)* ^(P-1)(MOD P)、
すなわち、^(P-1)≡1 (MOD P)
二次プロービング定理:
Nは、N> X> 0、式X 2%、N =溶液1:です。X = 1、X = N-1素数であり、場合
:プルーフ
1に加えて、この溶液X =外部、Nを満たすxの残り> X>√N、n²> X 2 > N;
そこX 2 = N + 1 2N + 1 3N + 1 ......(N-2)は、n + 1 ...(N-1)N + 1つの
素数ので、nがN従って、唯一の(N-2)は、n + 1は、正方形に、すなわち、X = N-1の難分解形成してもよいです。
ポラードのRho アルゴリズム一定の確率で、それは、より信頼性の高い1ボードと考えられ、そして唯一の約4 ^の不当な有罪判決することができます( - s)は、sの値は、自己与えられている。
このアルゴリズムは、大きな数を打破し続けることです小数; フェルマーの小定理とPseudoprimeは満たす^(N-1)≡ことを、nは場合は正の整数であると考えた場合、nは互いに素正の整数を理解 1(mod nを)が、 我々はnがあると言います擬似素数Aに基づきます。数が擬似素数であれば、それはほぼ確実に素数である、複数のクエリは、偽陽性の確率は非常に低いとすることができる。したがって、このような係数pを見つけるために、乱数X1を構築し続けるので、P = GCD(X1-X2、 N-); P == 1つのビルダーは、常にX1とX2を調整する、失敗した場合、そうでない場合はpは再帰の要因は、pを検索し続け、そしてn / pがベースです。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
long long factor[1000005];
int tot;
const int S=50;
long long mult(long long a,long long b,long long c)
{
a%=c;
b%=c;
long long ret=0;
while(b)
{
if(b&1)
{
ret=(ret+a)%c;
}
b>>=1;
a<<=1;
if(a>=c)a%=c;
}
return ret;
}
long long pow(long long x,long long n,long long mod)
{
if(n==1)return x%mod;
x%=mod;
long long tmp=x;
long long ret=1;
while(n)
{
if(n&1)
{
ret=mult(ret,tmp,mod);
}
tmp=mult(tmp,tmp,mod);
n>>=1;
}
return ret;
}
bool check(long long a,long long n,long long x,long long t)
{
long long ret=pow(a,x,n);
long long last=ret;
for(int i=1;i<=t;i++)
{
ret=mult(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(long long n)//判素数
{
if(n<2)return false;
if(n==2) return true;
if((n&1)==0)return false;
long long x=n-1;
long long t=0;
while((x&1)==0)
{
x>>=1;
t++;
}
for(int i=0;i<S;i++)
{
long long a=rand()%(n-1)+1;
if(check(a,n,x,t))//如果检查出来是合数
return false;
}
return true;
}
long long gcd(long long a,long long b)
{
if(a==0)return 1;
if(a<0)return gcd(-a,b);
while(b)
{
long long t=a%b;
a=b;
b=t;
}
return a;
}
long long pollard_rho(long x,long long c)
{
long long i=1,k=2;
long long x0=rand()%x;
long long y=x0;
while(1)
{
i++;
x0=(mult(x0,x0,x)+c)%x;
long long d=gcd(y-x0,x);
if(d!=1&&d!=x)return d;
if(y==x0)return x;
if(i==k)
{
y=x0;
k+=k;
}
}
}
void findphi(long long n)
{
if(miller_rabin(n))
{
factor[tot++]=n;
return;
}
long long p=n;
while(p>=n)
{
p=pollard_rho(p,rand()%(n-1)+1);
}
findphi(p);
findphi(n/p);
}
int main()
{
long long n;
while(scanf("%I64d",&n)!=EOF)
{
tot=0;
findphi(n);
for(int i=0;i<tot;i++)
printf("%I64d",factor[i]),printf("\n");
if(miller_rabin(n))printf("yes\n");
else printf("no\n");
}
return 0;
}