0812 large a n mod p

ph
Admin (토론 | 기여)님의 2017년 8월 31일 (목) 13:15 판
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)
이동: 둘러보기, 검색

problem : for very large natural numbers \(a, n, p\), find the value of \(a^n \pmod{p}\).

Below process is finding the period. But it will appear to be unnecessary.

def a_exp_n_mod_p(a,n,p):
    # `a` can be factorized. but it does not applied here, maybe it will make this much slower. 
    # Factorization is a very expensive process.
    assert a > 0 and n > 0 and p > 0
    if a%p ==0 :
        return 0
    
    # find the period.
    # a^(2^n) has a period.
    LIMIT = 10000 # period limit
    x = [0]*LIMIT
    anmodp = a%p
    for i in range(LIMIT):
        if anmodp in x:
            x = x[:i]
            for j in range(len(x)):
                if x[j]==anmodp:
                    break
            break
        x[i] = anmodp
        anmodp *= anmodp 
        anmodp %= p
    
    assert len(x) < LIMIT
    period_len = len(x)-j
    #print period_len
    #print len(x)
    digit = 0
    r = 1
    while n>0:
        if n%2 == 1:
            r *= x[digit]
            r %= p
        n /= 2
        digit += 1
        if digit >= len(x):
            digit -= period_len
            assert digit >= 0
    
    return r
    
            
assert a_exp_n_mod_p(3,20,20) == pow(3,20)%20
assert a_exp_n_mod_p(12,15,20) == pow(12,15)%20
assert a_exp_n_mod_p(12,15,19) == pow(12,15)%19
assert a_exp_n_mod_p(4,15,497) == pow(4,15)%497
print a_exp_n_mod_p(2032343532,24234234324,2342434234)
1368242842 


Below will be enough.

def anmodp(a, n, p):
    if n==1:
        return a%p

    tmp = anmodp(a, n/2, p)
    if n%2==1: #odd
        return (a*(tmp**2))%p
    else:
        return (tmp**2)%p

\(O(\log n)\) process can use recursive call freely.

blog comments powered by Disqus