對a的b次方取模
取模肯定是一邊算一邊取模(防止計算過程的溢位)
所以只考慮實現a的b次方
快速冪
就直接說寫法和一些理解:
計算a ^ b,如果把 b 寫成2 進製,如13 的二進位制 1101,於是3 號位 、2號位、0號位就都是1(就不證明了,去了解一些二進位制就會了),那麼就可以得到13 = 2^3 + 2^2 + 2^1 = 8 + 4 + 1。所以a ^13 = a^8 * a^4 * a^1。
核心1:
把b轉換成二進位制,然和將b的二進位制數從右到左判斷,如果判斷為1,則ans乘上當前的次方
eg: 3^5-> 3^(101)–>第零位表為1,則ans就要乘 a^( 2^0 ),然後第一位為0,不操作,第二位為1,ans乘上a^( 2^2)–>ans = 1(ans的初始值) * a^( 2^0 ) (第一次操作) * a^( 2^2)(第二次操作)
核心2:
每次迴圈的時候不管要不要對ans進行操作,都要對a進行一次操作,即a = a * a,假如到了第n此迴圈,此時正在判斷b的二進位制的第n-1位是否為1。又因為a在第一次進入迴圈時,為a^1 ,即a^( 2^0) ,那麼第n次迴圈就是a^( 2^n-1),正好b正在判斷第n-1位,此時如果為1,則直接將ans = ans * a 即可。
最後還有二進位制的一些操作
按位與&(都為1的時候為1)
按位或|(有1就變1)
異或^ (不同為1,相同為0)
運用:求n的第k位數字: n >> k & 1(k的第n位為1,則為真)
-n的求法:取反碼,然後加1(符號位變為1)
2(010)-> -2(101 + 1 -> 110)
只留下n的最後一位1:lowbit(n) = n & -n
n的最後乙個1變為0:n&(n - 1)
最後注意取模
**
#include
#include
using
namespace std;
intmain()
b >>=1;
a =1ll* a * a % p;
} cout << ans << endl;
return0;
}
求a的b次方 a的b次方對m取模
如計算2 13,則傳統做法需要進行12次乘法,但是可以優化 把2 2的結果儲存起來看看,是不是成了 4 4 4 4 4 4 2 再把4 4的結果儲存起來 16 16 16 2 一共5次運算,分別是2 2 4 4和16 16 16 2 這樣分析,我們演算法因該是只需要計算一半都不到的乘法了。為了講清這...
高次方求模
有了這個公式,求解問題就簡單了,n的p次方很容易拆分為幾個數相乘的形式。其中採用二分法拆分較為簡單高效。遞迴 cpp view plain copy print?define m 10003 int powmod int n,int p int temp pow n,p 2 int result t...
求a的b次方,a b
求 a 的 b 次方對 p 取模的值。輸入格式 三個整數 a,b,p 在同一行用空格隔開。輸出格式 輸出乙個整數,表示a b mod p的值。資料範圍 1 a,b,p 10e9 輸入樣例 3 2 7輸出樣例 2 includeusing namespace std include include i...