學習筆記----快速冪取模演算法
轉自部落格:http://www.cnblogs.com/E-star/archive/2012/05/05/2484601.htm
向寶哥學習!
1:利用a^b%n = (((a%c)*a)%c......)運算計算時間複雜度認為得到優化,O(b),但b很大是還是不行。
int modexp_simple( int a, int b, int n) { int ret
= 1; while (b--) { ret
= a * ret % n; } return ret; } |
2:
演算法2:另一種演算法利用了二分的思想,可以達到O(logn)。
可以把b按二進位制展開為:b = p(n)*2^n + p(n-1)*2^(n-1) +…+ p(1)*2 + p(0)
其中p(i) (0<=i<=n)為 0 或 1
這樣 a^b = a^ (p(n)*2^n + p(n-1)*2^(n-1) +...+ p(1)*2 + p(0))
= a^(p(n)*2^n) * a^(p(n-1)*2^(n-1)) *...* a^(p(1)*2) * a^p(0)
對於p(i)=0的情況, a^(p(i) * 2^(i-1) ) = a^0 = 1,不用處理
我們要考慮的僅僅是p(i)=1的情況
化簡:a^(2^i) = a^(2^(i-1) * 2) = ( a^( p(i) * 2^(i-1) ) )^2
利用這一點,我們可以遞推地算出所有的a^(2^i)
當然由演算法1的結論,我們加上取模運算:
a^(2^i)%c = ( (a^(2^(i-1))%c) * a^(2^(i-1))) %c
於是再把所有滿足p(i)=1的a^(2^i)%c按照演算法1乘起來再%c就是結果, 即二進位制掃描從最高位一直掃描到最低位
當然由演算法1的結論,我們加上取模運算:
a^(2^i)%c = ( (a^(2^(i-1))%c) * a^(2^(i-1))) %c
於是再把所有滿足p(i)=1的a^(2^i)%c按照演算法1乘起來再%c就是結果, 即二進位制掃描從最高位一直掃描到最低位
非遞迴演算法:
#include
<iostream> #define
ll long long using namespace std; //計算a^b
mod n ll
modexp(ll a,ll b,ll n) { ll
ret=1; ll
tmp=a; while (b) { //基數存在 if (b&0x1)
ret=ret*tmp%n; tmp=tmp*tmp%n; //
計算a^(2*i) 但b的二進位制位是0的時候相當於ret*1所以不用考慮 b>>=1; } return ret; } int main() { cout<<modexp(2,10,3)<<endl; return 0; } |
遞迴實現:
/計算a^bmodn int modexp_recursion( int a, int b, int n) { int t
= 1; if (b
== 0) return 1; if (b
== 1) return a%n; t
= modexp_recursion(a, b>>1, n); t
= t*t % n; if (b&0x1) { t
= t*a % n; } return t; } |
參考:http://blog.csdn.net/lsldd/article/details/5506933
模板:
ll
modmul(ll a,ll b, ll mod) { ll
res = 0; ll
tmp = a; while (b) { if (b&1)
res = (res + tmp)%mod; tmp
= (tmp+tmp)%mod; b>>=1; } return res; } ll
modexp(ll a,ll b,ll mod) { ll
res = 1; ll
tmp = a; while (b) { if (b&1)
res = modmul(res,tmp,mod); tmp
= modmul(tmp,tmp,mod); b>>=1; } return res; } |
相關文章
- Raising Modulo (快速冪取模)AI
- 集合冪級數學習筆記筆記
- HDU 1575 Tr A【矩陣快速冪取模】矩陣
- 演算法學習:矩陣快速冪/矩陣加速演算法矩陣
- 【演算法學習筆記】快速傅立葉變換演算法筆記
- FZU1759Super A^B mod C(快速冪取模) 公式公式
- 模擬退火 學習筆記筆記
- 模擬退火學習筆記筆記
- Proteus模擬學習筆記筆記
- 演算法學習筆記演算法筆記
- 快速傅立葉變換 學習筆記筆記
- LMF演算法學習筆記演算法筆記
- 機器學習演算法學習筆記機器學習演算法筆記
- 匈牙利演算法學習筆記演算法筆記
- 學習筆記----KM演算法筆記演算法
- 學習筆記----RMQ演算法筆記MQ演算法
- EM演算法學習筆記演算法筆記
- Floyd演算法學習筆記演算法筆記
- Tarjan 演算法學習筆記演算法筆記
- 【MongoDB學習筆記】MongoDB 快速入門MongoDB筆記
- JavaScript學習筆記1—快速入門JavaScript筆記
- 演算法學習筆記:Kosaraju演算法演算法筆記
- 模擬積體電路學習筆記筆記
- 類歐幾里得演算法學習筆記演算法筆記
- 《演算法導論》學習筆記演算法筆記
- 莫隊演算法學習筆記演算法筆記
- 快速冪演算法及其擴充演算法
- Spring Boot 學習筆記(1):快速上手Spring Boot筆記
- substrate學習筆記2:substrate快速入門筆記
- 快速沃爾什變換 (FWT)學習筆記筆記
- 演算法學習筆記(3.1): ST演算法演算法筆記
- 演算法學習筆記(1)- 演算法概述演算法筆記
- 演算法學習筆記:2-SAT演算法筆記
- 智慧演算法學習筆記(一) (轉)演算法筆記
- [演算法學習筆記] 並查集演算法筆記並查集
- Android 快取工具 DiskLruCache 學習筆記Android快取筆記
- 演算法學習筆記(40): 具體數學演算法筆記
- flask文件學習筆記1-快速入門Flask筆記