程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Miller Robin素數測試與Pollcard Rho因數分解

Miller Robin素數測試與Pollcard Rho因數分解

編輯:C++入門知識

<1>預備算法 [cpp]  LL mul(LL a, LL b, LL p)   {        LL rn=0, i;        for(i=1; i<=b; i<<=1,a=(a+a)%p)         if(b&i) rn=(rn+a)%p;        return rn;   } // 計算模意義下兩大數乘積   LL ksm(LL a, LL b, LL p)   {        LL rn=1;        for(; b; a=mul(a,a,p),b>>=1)         if(b&1) rn=mul(rn,a,p);        return rn;   } // 計算模意義下兩大數乘方   LL gcd(LL a, LL b)    {         LL tmp; if(a<b) tmp=a,a=b,b=tmp;        while(b) tmp=a%b, a=b, b=tmp;        return a;   } // 求最大公約數     <2>Miller Robin素數測試 能在(0.25)^S的錯誤率下判定質數,相應地需要付出(S*log n)的時間復雜度。 原理基於兩個定理: 1.若p是質數,0<a<p,那麼a^(p-1)≡1(mod p)。 2.對於0<x<p,x^2≡1(mod p) 有且只有兩解: x=1和x=p-1。 [cpp]  bool isprime(LL n)   {        if(n==2) return true;        if(n<2 || !(n&1)) return false;        LL a,x,y, u=n-1; int t=0;        while((u&1)==0) t++, u>>=1;        for(i=0; i<S; i++)        {         a=rand()%(n-1)+1;         x=ksm(a,u,n);         for(int j=1; j<=t; j++)         {              y=mul(x,x,n);              if(y==1 && x!=1 && x!=n-1) return false;              x=y;         }         if(x!=1) return false;        }        return true;   }       <3>Pollcard Rho因數分解 復雜度貌似是n^(1/4),這應該是因數分解的最快算法了。 [cpp]  void rho(LL n)   {        if(isprime(n)) { list[++top]=n; return; }        LL a,x,y,z,p;        while(true)        {         for(x=1,y=1,z=rand()+1,p=1; p==1; )         {  www.2cto.com            y = (mul(y,y,n)+z)%n;              p = gcd((x-y+n)%n,n);              x = (mul(x,x,n)+z)%n;              y = (mul(y,y,n)+z)%n;         }         if(p==n) continue;         rho(p); rho(n/p);         return;        }   }   正確性是顯然的,復雜度分析麼——總之很快。  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved