【复习】快速幂算法详解
快速冪算法
就是求一個高精度冪次取余時的一個快速算法
比如我們要求aba^bab%m的時候
應用于快速冪算法 也就是將O(n)轉化為O(logn)的算法
他的原理就是:
252^525 = 2?2?2?2?22*2*2*2*22?2?2?2?2 = 21012^{101}2101 = 21?242^1 * 2^421?24
相當于我們只需要遍歷冪次的二進制位的長度就可以了
我們知道任意數x的二進制位長度是log2(x)
這樣大大提升了求冪的效率
可是這樣運算容易導致數據溢出
如何保證運算不超出數據范圍還能正確求余呢?
我們需要借助同余定理 解決在這個求冪的運算過程中所產生的高精度問題
如 252^525%m
同余定理 就是給你定一個正整數m(m>1) 如果兩個整數 a 和b 滿足 a-b能夠被m整除 則(a-b)/m
得到一個整數 則稱a,b對模m同余
同余定理兩個應用是
(a+b)%m = (a%m+b%m)%m
(a?ba * ba?b)%m = (a%m ?*? b%m)%m
以上兩條等式可以分別證明
這兩條性質 可以應用在高精度運算中
實際上高精度就是說參與運算的數據和運算結果的范圍, 超出標準數據類型能表示的數據大小范圍的運算。
這個時候,如果要得到正確的計算結果,顯然不能依靠普通方法實現了。 而要在普通運算原理的基礎上,加以輔助算法來實現超大數據的計算。
例如:求兩個100位的數據的和,或者計算兩個100位的數字乘積。這時就要用到高精度算法了。
下面我們來看下代碼
typedef long long ll; ll quickpow(ll a,ll b,ll m){ll ans = 1;while(b){if(b%2)ans*=a;a*=a,a%=m;//套括號取模ans%=m;//套括號取模b>>=1;}return ans%m;//套括號取模 }以上代碼如果用表達式表達出來的話 就是
((ans?aans*aans?a) % m ?(a?a)* ( a * a )?(a?a) % m ?(a?a)* ( a * a )?(a?a) % m ) % m = 1?251 *2^51?25 %m
這個完全就是我們上面寫的那個同余定理的應用中對高精度取余的處理方式
那么也就是 ((1?2)?(2?2)?(2?2))((1*2)*(2*2)*(2*2))((1?2)?(2?2)?(2?2))%m = [(1?2)[(1*2)[(1?2)%m ?((2?2)* (( 2*2)?((2?2)%m?(2?2)*(2*2)?(2?2)%m)))%m]]]%m
所以在這個過程中既不會低效 也不會導致數據溢出
這就是快速冪算法
總結
以上是生活随笔為你收集整理的【复习】快速幂算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交换机端口tagged与untagged
- 下一篇: 分布式搜索 Elasticsearch