在miller rabbin測試素數,就用到了快速冪取模的思想。這裡總結下。
求a^b%c(這就是著名的rsa公鑰的加密方法),當a,b很大時,直接求解這個問題不太可能
演算法1:利用公式a*b%c=((a%c)*b)%c,這樣每一步都進行這種處理,這就解決了a^b可能太大存不下的問題,但這個演算法的時間複雜度依然沒有得到優化
**如下:
int modexp_******(int a,int b,int n)演算法2:另一種演算法利用了二分的思想,可以達到o(logn)。return ret;
}
可以把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就是結果,即二進位制掃瞄從最高位一直掃瞄到最低位
例項**:遞迴
//計算a^bmodn例項**2:非遞迴優化int modexp_recursion(int a,int b,int n)
return t;
}
#includeusing namespace std;
//計算a^bmodn
int modexp(int a,int b,int n)
return ret;
}
int main()
returnd;}
快速冪取模演算法 模板
快速冪取模其實是a b c,這就是著名的rsa公鑰加密的方法,當a,b都很大的時候,直接求是不可取的,所以就用到了快速冪取模。首先你得明白他的原理,其實是用到了二分的思想,把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 c,這就是著名的rsa公鑰加密的方法,當a,b都很大的時候,直接求是不可取的,所以就用到了快速冪取模。首先你得明白他的原理,其實是用到了二分的思想,把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時,一般會用c 自帶的pow 函式對吧,可是加入資料十分大時,pow 是十分慢的,這個時候我們需要乙個能高效求出a b的演算法,這這時就出現了快速冪演算法。假如我們需要求3 999,那麼我們是不是可以發現3 999 3 512 256 128 64 32 4 2 1 3 5...