一、題目背景
已知底數a,指數b,取模值mo
求ans = ab % mo
二、樸素算法(已知可跳過)
ans = 1,循環從 i 到 b ,每次將 ans = ans * a % mo
時間復雜度O(b)
1 void power(int a,int b,int mo) 2 { 3 int i; 4 ans=1; 5 for (i=1;i<=b;i++) 6 { 7 ans*=a; 8 ans%=mo; 9 } 10 }
三、快速冪
先討論無需取模的
當b為偶數時:ab=a(b/2)*2=(a2)b/2
當b為奇數時:ab=a*ab-1=a*(a2)(b-1)/2
如 28=(22)4 27=2*(22)3
所以,我們可以如此迭代下去
210=(22)5=(22)*[(22)2]2
① ② ③
指數為10 是一個偶數,則底數2平方,指數變為一半 [ ①→② ]
指數為5 是一個奇數,則先將底數提出作為系數(22),此時指數為4 是一個偶數,則底數22再平方,指數再變為一半 [ ②→③ ]
歸納總結得到:
當指數大於1時,若為 偶數 則將指數除以2,底數平方
若為 奇數 則先提出一個為底數的系數(可直接把該系數乘進ans中),所以指數減1,然後再按照 偶數 的辦法做
不斷迭代下去,當指數為1時,則直接得出答案
最後只要將每次相乘時取模即可,時間復雜度O(log2b)
1 void power(int a,int b,int mo) 2 { 3 ans=1; 4 a%=mo; 5 while (b>0) 6 { 7 if (b%2==1) ans=ans*a%mo; 8 b/=2; 9 a=a*a%mo; 10 } 11 }