快速冪取模(a b mod)詳細解析

2021-09-12 16:40:30 字數 1435 閱讀 4447

快速冪實現的最基本的理論就是我們離散課上或者數論中學過的一條公式推出的引理。

積的取餘等於取餘的積的取餘。

再在這條引理的基礎之上,對指數型資料進行拆分以及合併,從而得到我們用的快速冪演算法。

對a^b進行分析。

對於當a和b較小是直接用int或者long存是沒有問題的,但是當a和b大到一定程度時,這就不是暴力存就

可以解決的問題了。我們應該怎麼去解決這個問題呢?

在這裡我們需要把注意力放在「大」字上面,正是由於a和b過大才導致的問題。所以我們要想辦法不斷地減

小a和b的規模,所謂逐個擊破。

根據上面的那條引理,我們知道了可以把指數拆開,從這個突破口突破。這裡我們就不難想到這樣乙個演算法:

/a是底數,b是指數,mode是取模數,sum是記錄取模的結果

int sum = 1;

a = a % mode;

for(int i = 1; i <= b; i++)

sum = sum % c;

這是直接利用的 引理而寫出來的**,這只是單純的降低的a的規模,但是這還達不到我們的要求,所以我們

需要進一步改進演算法。(當然還可以繼續降低啊的規模,即將迴圈中的那句換成sum = (sum * a)%mode)

我們已經實現的降低a的規模,所謂我們要想著怎麼降低b的規模。我們首先看兩個樣例:先看b為偶數的樣例

7^16,mode = 3,我們要怎麼進行拆分?

最基本的拆分是這樣的:7*7*7*7*7*7*7*7*7......7,上面的演算法只是將其變為1*1*1*1*1*1*1......1,那麼怎麼減少b

的規模呢?你應該有一點感覺了吧。就是兩兩合併,將(7^16)變成(49^8),這就降低了b的規模,再利用上面

的演算法降低a的規模,最終會變成1 *1*1*1*1*1*1*1。是不是感覺整個數簡單了很多。

按照這個思路,我們可以多迴圈幾次,從而不斷的降低a和b的規模。

那麼b為奇數怎麼辦呢?

其實也很簡單,我們只要在偶數演算法的基礎之上,每次把多出來的這個數跳出來,預先取模再帶入即可。

從而最終得出快速冪的**:

long long mode(long long a, long long b, long long mode)

return sum;

}

當然有時候你可能會碰到用&的運算子的**實現,其實和這個大致相同,只不過是用&操作符對b的奇偶性進行判斷而已

&的操作符:二進位制位中,1 & 1 = 1,其餘組合均為0

用&實現的**:

long long mode(long long a, long long b, long long mode)

b /= 2;

a = a * a % mode;

}return sum;

}

快速冪 快速冪取模

快速冪的思想在於快速求解高冪指數的冪運算 複雜度為o log2n 與樸素運算相比有很大的改進 接下來給出 其中有詳解 include include using namespace std typedef long long ll ll pow1 int a,int b 最常規的方法 將冪指數轉化為...

快速冪 快速冪取模

求x m 一般方法是 xm x xm 1,這樣需要做m次乘法,未免過慢。加速方法有兩種。1.基於當m為偶數時,xm x2 m 2 當m為奇數時,xm x xm 1。顯然當m為偶數時m會減半,當m為奇數時,下次就是偶數。m可以很快收斂到0.表示冪 2.將m看成二進位制串mkmk 1 m1m0,那麼xm...

快速冪 快速冪取模

原文 快速冪這個東西比較好理解,但實現起來到不老好辦,記了幾次老是忘,今天把它系統的總結一下防止忘記。首先,快速冪的目的就是做到快速求冪,假設我們要求a b,按照樸素演算法就是把a連乘b次,這樣一來時間複雜度是o b 也即是o n 級別,快速冪能做到o logn 快了好多好多。它的原理如下 假設我們...