[英]Placing of modulo operation in code
我一直在努力解決一個問題,其中解決方案歸結為計算價值
這就是我寫的。 如果答案超出10^9+7
,我需要打印my_answer%(10^9+7)
。
mod_val=10**9+7
current=[int(x) for x in raw_input().strip().split()]
m=current[0]-1
n=current[1]-1
hi,lo=max(m,n),min(m,n)
num_prod=1
den_prod=1
for each in xrange(1,lo+1):
den_prod=den_prod*each
num_prod=num_prod*(hi+each)
print (num_prod//den_prod)%mod_val
但是在完成所有計算之后,模運算就在底部。 有沒有辦法我可以在代碼之間的某處放置模運算,以節省計算或提高性能?
事實:
(m + n)C n =(m + n)! /(n!m!)= (1 / n!)*((m + n)!/ m!)
看代碼:
第1行: den_prod=den_prod*each
代表(1 / n!)
第2行: num_prod=num_prod*(hi+each)
表示((m + n)!/ m!)的簡化形式。
關鍵思想是在for
循環中使用模冪運算,然后對結果應用除以模運算。 除法運算變為模和逆的乘法。 最后,為了計算模逆,我們使用歐拉定理。
def mod_inv (a, b):
return pow(a, b - 2, b)
mod_val=10**9+7
current=[int(x) for x in raw_input().strip().split()]
m=current[0]-1
n=current[1]-1
hi,lo=max(m,n),min(m,n)
num_prod=1
den_prod=1
for each in xrange(1,lo+1):
den_prod = (den_prod*each) % mod_val
num_prod = (num_prod*(hi+each)) % mod_val
print (num_prod * mod_inv(den_prod, mod_val)) % mod_val
我為問題定了3種不同的解決方案。 定時5000組合:( 5000 C n
)其中n
從0到4999。
代碼1:上面的解決方案
def mod_inv (a, b):
return pow(a, b - 2, b)
mod_val=10**9+7
hi = 5000
for lo in range(0, hi-1):
# Code 1
num_prod=1
den_prod=1
for each in xrange(1,lo+1):
den_prod = (den_prod*each) % mod_val
num_prod = (num_prod*(hi+each)) % mod_val
output = (num_prod * mod_inv(den_prod, mod_val)) % mod_val
# print output
時間1:
real 0m3.607s
user 0m3.594s
sys 0m0.011s
代碼2:您提出的解決方案
mod_val=10**9+7
hi = 5000
for lo in range(0, hi-1):
# Code 2
test1 = 1
test2 = 1
for each in xrange(1,lo+1):
test1 = (test1*each)
test2 = (test2*(hi+each))
test_output = (test2 / test1) % mod_val
# print test_output
時間2:
real 0m25.377s
user 0m25.337s
sys 0m0.027s
代碼3: scipy
解決方案
from scipy.misc import comb
hi = 5000
for lo in range(0, hi-1):
# Code 3
c = comb(hi+lo, lo, exact=True)
# print c
時間3:
real 0m36.700s
user 0m36.639s
sys 0m0.048s
def mod_inv (a, b):
return pow(a, b - 2, b)
def small_nCr (n, r, mod):
hi = max(r, (n - r))
lo = min(r, (n - r))
num_prod=1
den_prod=1
for each in range (1, lo + 1):
den_prod = (den_prod * each) % mod
num_prod = (num_prod * (hi + each)) % mod
small_c = (num_prod * mod_inv (den_prod, mod)) % mod
return small_c
def lucas (n, r, mod):
c = 1
while (n > 0 or r > 0):
ni = n % mod
ri = r % mod
if (ri > ni):
return 0
c = c * small_nCr (ni, ri, mod)
n = n / mod
r = r / mod
return c
def nCr (n, r, mod):
return lucas (n, r, mod) % mod
注意:如果模數值不是素數,則可以應用中國剩余定理。
資料來源:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.