1. 程式人生 > >Pollard's Rho 快速質因數分解 複習小記

Pollard's Rho 快速質因數分解 複習小記

Description

為什麼又是複習小記?因為又忘了個精光QAQ

Pollard’s Rho

分治思想

我們實現過程find(n)表示對n進行質因數分解。
如果能找到任意一個d|n,d1,dn,那麼就可以轉化成兩個子問題find(d)find(n/d)。當然如果n本身就是質數那麼肯定是找不到的,所以先用miller rabin質數測試判定一次

隨機演算法的改進

如果每次隨機x並判定(x,n)是否等於1,效率太低

基於生日悖論的概率原理

1n中選k個數,其中至少一對數之差為n的因數的概率隨著k增大而迅速增大。
這啟示我們判定(abs(xy),n)是否為1

,這樣成功概率會更高

步驟

  1. 定義函式f(x)=x2+cc隨機給出
  2. 注意到因為是模n意義下,所以x的取值會成環,類似ρ
  3. x每次走一步,y每到2j的時間點走一次(最玄學的部分)
  4. 每次判定(abs(xy),n)是否為1
  5. x=y則退出,重新隨機c

板子

ll pollard_rho(ll n,ll c)
{
    int i=1,k=2;
    ll x=rand()%n;ll y=x;
    for(;;)
    {
        i++;
        x=(qmul(x,x,n)+c)%n;
        ll d=gcd(abs(x-y),n);
        if
(d!=1 && d!=n) return d; if(y==x) return n; if(i==k) y=x,k<<=1; } } void find(ll n) { if(n==1) return; if(miller_rabin(n)) { a[++num]=n; return; } ll d=n; while(d>=n) d=pollard_rho(n,rand()%(n-1)+1); find(d); while(n%d
==0) n/=d; find(n); }