快速冪演算法:
1,背景
給定三個整數a、b、m(a < 10^9, b < 10^6, 1< m < 10^9),求a^b%m
typedef long long ll;
ll pow(ll a, ll b, ll m)
return ans; }
給定三個整數a、b、m(a < 10^9, b < 10^18, 1< m < 10^9),求a^b%m
這裡用上面的做法顯然是不行的,o(b)已經到了10^18
這裡將使用快速冪演算法
2,快速冪演算法(遞迴)
a,如果b是奇數,那麼有a^b = a* a^(b-1)
b,如果b是偶數,那麼有a^b = a^(b/2)*a^(b/2)
這樣,在log(b)級別次數的轉換後,就可以把b轉變為0,而任何正整數的0次方都是1
舉個例子,如果計算2^10:
1)2^10———2^5, 2^10= 2^5*2^5
2)2^5———2^4, 2^5 = 2 * 2^4
3)2^4———2^2, 2^4 = 2^4 * 2*4
4)2^2———2^1, 2^2 = 2^1 *2^1
5)2^1———2^0, 2^1 = 2 * 2^0
6)2^0 = 1, 然後從下往上一次會退計算即可
這顯然是遞迴的思想,於是可以得到快速冪的遞迴寫法,時間複雜度為o(logb)
typedef long long ll;
ll binarypow(ll a, ll b, ll m)
}
⚠️:
1)如果初始a有可能大於等於m,那麼需要在進入函式前,就讓a對m取模
2)如果m為1,可以直接在函式外部特判為0,不需要進入函式計算(因為任何正整數對1取模一定等於0)
3,快速冪演算法(迭代)
對於a^b來說,如果把b寫成二進位制,那麼b就可以寫成若干次二次冪之和,
例如13的二進位制1101,就可以寫成13 = 2^3 + 2^2 +2^0 = 8 + 4 +1
所以a^13 = a^(8+4+1)=a^8 * a^4 * a^1
通過同樣的方式,我們可以把任意的a^b表示為a^2k、。。。、a^8、a^4、a^2、a^1中若干項的乘積
步驟:1)初始令ans為1,用來存放累計的結果
2)判斷b的二進位制末尾是否為1(即判斷b&1 是否為1,也可以理解為判斷b是否為奇數),如果是的話,令ans乘上a的值
3)令a平方,並將b右移一位(也可以理解為將b除以2)
4)只要b大於0,就返回2)
typedef long long ll;
ll binarypow(ll a, ll b, ll m)
a = a * a % m; //令a開平方
b >>= 1; //將b的二進位制右移一位
}return ans;
}
快速冪運算
知識點 快速冪運算 快速冪運算 原來 當我們計算a k時候,一定是 a a a a a k個 現在 把k拆成二進位制,為了表達清楚,我們這裡讓k 11 11 dec 1011 b 1 2 3 0 2 2 1 2 1 1 2 0 我們會發現其中有0的地方是個廢操作 那麼我們將去除這個廢操作的過程叫做快...
快速冪運算
如果我們要求x n次方 當n很大的時候 會gg 這個時候就會用到快速冪演算法了,顧名思義,快速冪,快速求冪。因為任何乙個數都可以用2進製表示。比如9 2 3 2 0 7 2 2 2 1 2 0 所以我們可以把n看成 n 2 k1 2 k2 2 k3.這樣來表示。當然我們同樣可以把x用這樣表示。即 x...
快速冪運算
首先,快速冪的目的就是做到快速求冪,假設我們要求a b,按照樸素演算法就是把a連乘b次,這樣一來時間複雜度是o b 也即是o n 級別,快速冪能做到o logn 快了好多好多。它的原理如下 假設我們要求a b,那麼其實b是可以拆成二進位制的,該二進位制數第i位的權為2 i 1 例如當b 11時 a1...