部落格停了差不多三個月, 雖然這一段時間在學演算法, 但從來沒有寫部落格。 今天看了一上午的快速冪,突然想寫寫部落格, 增加一下自己的記憶!這個博文知識簡單介紹一下演算法中取餘的原因
1至於快速冪的概念不詳細記錄了。當我們想求a的b次冪對c取余時,我們會直接想到用這個演算法:
int ans = 1;這個演算法的時間複雜度體現在for迴圈中,為o(b).這個演算法存在著明顯的問題,如果a和b過大,很容易就會溢位。因此需要用到離散數學知識(該知識點我也沒學過,度娘教的^_^)for( i = 1; i <= b; i++)
ans %= c;
定理1:
2由上面的公式可以推出:
把a看成 a * 1, 故由定理1可得出上面的公式。由此得到改進版本:
int ans = 1這個演算法在時間複雜度上沒有改進,仍為o(b),不過已經好很多的,但是在c過大的條件下,還是很有可能超時,所以,我們推出以下的快速冪演算法。; a = a % c; //
加上這一句
for(int i = 1;i<=b;i++)
ans = ans % c;
3快速冪演算法依賴於以下明顯的公式,我就不證明了,很簡單理解。
4由此得到改進版本:
int ans = 15我們可以看到,我們把時間複雜度變成了o(b/2).當然,這樣子治標不治本。但我們可以看到,當我們令k = (a * a) mod c時,; 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;
狀態已經發生了變化,我們所要求的最終結果即為(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 = 17將上述的**結構化,也就是寫成函式:; a = a %c;
while(b>0
)
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 講到二進位制 一般都會想到這兩...