初學 快速冪 的理解

2022-07-27 04:54:09 字數 1883 閱讀 2038

部落格停了差不多三個月, 雖然這一段時間在學演算法, 但從來沒有寫部落格。 今天看了一上午的快速冪,突然想寫寫部落格, 增加一下自己的記憶!這個博文知識簡單介紹一下演算法中取餘的原因

1至於快速冪的概念不詳細記錄了。當我們想求a的b次冪對c取余時,我們會直接想到用這個演算法:

int ans = 1;  

for( i = 1; i <= b; i++)

ans %= c;

這個演算法的時間複雜度體現在for迴圈中,為o(b).這個演算法存在著明顯的問題,如果a和b過大,很容易就會溢位。因此需要用到離散數學知識(該知識點我也沒學過,度娘教的^_^)

定理1:

2由上面的公式可以推出: 

把a看成 a * 1, 故由定理1可得出上面的公式。由此得到改進版本:

int ans = 1

;   a = a % c; //

加上這一句

for(int i = 1;i<=b;i++)

ans = ans % c;

這個演算法在時間複雜度上沒有改進,仍為o(b),不過已經好很多的,但是在c過大的條件下,還是很有可能超時,所以,我們推出以下的快速冪演算法。

3快速冪演算法依賴於以下明顯的公式,我就不證明了,很簡單理解。

4由此得到改進版本:

int ans = 1

;  a = a %c;

if(b%2==1

)   ans = (ans * a) mod c; //

如果是奇數,要多求一步,可以提前算到ans中

k = (a*a) % c; //

我們取a2而不是a

for(int i = 1;i<=b/2;i++)

ans = ans % c;

5我們可以看到,我們把時間複雜度變成了o(b/2).當然,這樣子治標不治本。但我們可以看到,當我們令k = (a * a) mod c時,

狀態已經發生了變化,我們所要求的最終結果即為(k)^b/2 mod c而不是原來的a^b mod c,所以我們發現這個過程是可以迭代下去的。

((迭代就是把這一次算的值作為下一次迴圈的初始值,所以可以更簡化該演算法))

當然,對於奇數的情形會多出一項a mod c,所以為了完成迭代,當b是奇數時,我們通過  ans = (ans * a) % c;來彌補多出來的這一項,

此時剩餘的部分就可以進行迭代了。   形如上式的迭代下去後,當b=0時,所有的因子都已經相乘,演算法結束。於是便可以在o(log b)的時間內完成了。

於是,有了最終的演算法:快速冪演算法。

((說實話, 我對這個簡化有點糊塗,關於在o(log b)的時間內就可以完成, 就假裝懂了吧, 以後慢慢理解吧))

6

int ans = 1

;   a = a %c;

while(b>0

)  

7將上述的**結構化,也就是寫成函式:

int powermod(int a, int b, int

c)  

return

ans;

}

這就是最後的優化**了。以上內容是抄襲的, 只不過自己又寫了一遍。如果看不懂我寫的的可以點下面**:

pvmhfcyydzghyrneum_oztpxwo

有關於快速冪的演算法的推導,還可以從另乙個角度來想。我就不介紹了。

初學演算法之快速冪

目前遇到需要用快速冪的題,大多都是與取模有關且直接乘會爆資料的題。因此,在講快速冪之前,我們得先了解下取模運算。基本性質 若p a b 則a b p 例如 11 4 7 18 4 7 a p b p 意味a b p 對稱性 a b p 等價於b a p 傳遞性 若a b p 且b c p 則a c ...

快速冪的演算法理解

一直聽說過快速冪,一直沒有用過。這下稍微有了點空閒時間,做個筆記自己看看。求乙個數的n次冪常見的是n次迴圈。例如。double power double base,int exponent while exponent return flag?1 total total 複雜度是o n 快速冪演算法...

對快速冪的理解 C )

時間複雜度是o n 級別,而快速冪能做到o logn 其實b是可以拆成二進位制的,該二進位制數第i位的權 值 為2 i 1 比如說b 11時 11的二進位制是1011,這三項 好像 不怎麼不好求 指數 你可以用longlong 或者用mod也可以 return ret 講到二進位制 一般都會想到這兩...