多数の因数分解は、Rhoをポラード

  1. クイック&高速電力乗ります
  2. フェルマーの小定理
  3. 定理二次プローブ
  4. pollorロー
  5. ミラー上昇

ポータルhdu3864

導入にポラードのロー乗算の多数等月長い長いバーストためのアルゴリズムの前に、迅速な乗算および迅速電力を普及します。

#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;
    }
公開された20元の記事 ウォンの賞賛1 ビュー6325

おすすめ

転載: blog.csdn.net/yichengchangan/article/details/71643615