1. 程式人生 > >快速冪求餘

快速冪求餘

快速冪問題(求a^b)

我們都知道當指數為偶數的時候,對於a**b,可以變為(a ** 2) ** (b/2)。
而當指數為奇數的時候,對於a ** b,可以化簡為a*(a ** (b-1)),然後即可以化簡為a*((a ** 2) ** ((b-1)/2))
如此我們便可知道 如果b為奇數,則將b減一除二,將一個a取到外面,同時對裡面的a平方。
如果b為偶數,則直接除二,同時對a平方。
若b為7,a為2。
則a變為4,b變為3,ans變為2*(2 ** 2) ** 3。
然後繼續向後運,(注意此時a為4),a變為16,b變為1,ans變為2* 4*(2 ** 2 ** 2) ** 1。
結果為128。

若b為10,a為2。
則a變為4,b變為5,ans變(2 ** 2) ** 5。
然後繼續向後運,(注意此時a為4),a變為16,b變為2,ans變為4*(2 ** 2 ** 2) ** 2。
再之後(注意此時a為16),a變為256,b變為1,ans變為4*(2 ** 2 ** 2 ** 2) ** 1。
結果為1024。

在這應注意b每次變化的時候都會對a平方(當然,也可以當b為奇數的時候使b減一,然後再判斷為偶數),為不影響結果,在這我們應該在引入一個變數(ans),在對b進行加減的時候我們應匯出一個a對ans進行變換,而不是直接改變a。只有當b除2時才對a進行改變,使其平方。

求a ** b%c
程式碼如下:

n=int(input())
for i in range(n):
    a,b,c=[int(x)for x in input().split()]
    a=a%c #由取模的運算規則可知 a**b%c=(a%c)**b%c
    ans=1
    while b!=0:
        if b%2==1:#若b為奇數
            b=b//2#b-1除2,直接取整商即可
            ans=(ans*a)%c#若為奇數則控制ans乘一個此時的a
        else:#若b為偶數
            b=b/2 #直接除2即可
        a=(a*a)%c#因與判斷平行 即每次執行均會對a平方
    print(ans)#應注意因為取模運算較大 應在每次執行程式是均對結果取模

該方法根據二進位制方法改編
原式如下

while b!=0:
        if b&1:
            ans=(ans*a)%c
        b>>=1        
        a=(a*a)%c