簡體   English   中英

尋找涉及指數和除數涉及大數的余數mod

[英]Finding remainder mod involving exponent and division involving huge numbers

我需要一個快速算法來評估以下內容

((a^n-1)/(a-1)) % p

an幾乎相等但小於10 ^ 6而p是固定的素數(假設p=1000003 )。 我需要在1秒內計算出來。 我正在使用python。 Wolfram Mathematica 立即計算它 使用以下代碼需要35.2170000076秒

print (((10**6)**(10**6)-1)/((10**6)-1))%1000003

如果那個分母a-1不存在,我可以將權力分組到更小的順序並使用關系a*b (mod c) = (a (mod c) * b (mod c)) (mod c)但是分母是當下。

如何用快速算法評估這個? 沒有numpy / scipy可用。

更新::這是我提出的最終代碼

def exp_div_mod(a, n, p):
    r = pow(a, n, p*(a-1)) - 1
    r = r - 1 if r == -1 else r
    return r/(a-1)

(((a ** n) - 1)/(a-1))%p

可以改寫為

(((a ** n) - 1)%((a-1)* p))/(a-1)

這部分:

(((a ** n) - 1)%((a-1)* p))

可以通過計算:

((a ** n)%((a-1)* p))

然后調整為-1。

通過((a-1)* p)將a增加到第n次冪和mod。 這可以使用Python pow()函數完成。 然后調整-1並除以a-1。

使用pow()函數並傳遞模數值比計算完整指數然后取模數更快,因為模數可以應用於計算的每個階段的部分乘積,這會使值停止變得太大( 10 6的功率10 6有6百萬個十進制數字,每一步都應用模數值,從不必大於模數的大小 - 在本例中約為13位數)。

碼:

def exp_div_mod(a, n, p):
    m = p * (a - 1)
    return ((pow(a, n, m) - 1) % m) // (a - 1);

print exp_div_mod((10**6), (10**6), 1000003)

輸出:

444446

注意:此方法僅在a,n和p為整數時有效。

一個 N-1)/(A-1)是從i = 0 IN-1的總和。

計算后者模p是直接的,基於以下內容:

如果n > 0則令Fan )為Σ( i = 0 ... n-1 ){ a i },否則為0。

現在:

  1. Fan )= a × Fan -1)+ 1

  2. ) = ( a +1)× F ( a 2 ,n) Fa ,2 )=( a +1)× Fa 2 ,n)

第二個身份是分而治之的遞歸。

由於這兩者都只涉及加法和乘法,我們可以通過分布模運算來計算它們mod p而不需要大於a × p的整數類型。 (見下面的代碼。)

只需第一次遞歸,我們就可以編寫迭代解決方案:

def sum_of_powers(a, n, p):
  sum = 0
  for i in range(n): sum = (a * sum + 1) % p
  return sum

使用分而治之的遞歸,我們得到的東西並不復雜得多:

def sum_of_powers(a, n, p):
  if n % 2 == 1:
    return (a * sum_of_powers(a, n-1, p) + 1) % p
  elif n > 0:
    return ((a + 1) * sum_of_powers(a * a % p, n // 2, p)) % p
  else:
    return 0

第一個解決方案在不到一秒的時間內返回,n == 10 6 第二個即時返回,即使n大到10 9

您可以乘以p - 1模逆 由於費馬的小定理,對於所有0 <x <p ,你有x p-2 ·x≡xp - 1≡1(mod p) ,因此你甚至不需要擴展的Euclid來計算逆,只需要pow標准Python的功能:

(pow(a, n, p) - 1) * pow(a - 1, p - 2, p) % p

該算法具有時間復雜度𝒪(log p),因為使用了square-and-multiply

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM