一、快速冪
快速冪是用於解決類似 $a^b$ $mod$ $p$值型別的問題的。使用普通的方法是從$1$迴圈至$b$,再逐次累乘,逐次取模。但這種方法對於$b$很大的時候卻可能會超時。那麼,這時候我們就需要使用快速冪了。
快速冪是基於以下式子:
若$b$ $mod$ $2=1$,則$a^b=a^\frac\times a^\frac\times a$
若$b$ $mod$ $2=0$,則$a^b=a^\frac\times a^\frac$
這樣,我們便通過分治將乙個大問題變為兩個小問題,再逐項計算,並取模。
另外,再加上兩個邊界條件:
$a^0=1$,$a^1=a$
例如下面的例子:
$3^7=3^3\times3^3\times3=(3^1\times3^1\times3)\times(3^1\times3^1\times3)\times 3$
其中,所有的式子都可以直接進行計算了,其時間複雜度為$\theta(log_2b)$。
其程式如下:
int _pow(int a,intb)
二、快速乘
快速乘常與快速冪結合在一起。當模數$p$過大時,乘起來可能會超過$long$ $long$的範圍。所以,我們也可以借助快速冪的思想在中間優化一下乘法。
注意到乘法$a\times b$可以轉化為$\underbrace_$,所以我們也能夠通過分治方法將其轉化。
例如下面的例子:
$3\times7=3\times3+3\times3+3=(3\times1+3\times1+3)+(3\times1+3\times1+3)+3$
其中,所有的式子也可以進行計算,複雜度依然為$\theta(log_2b)$。
快速乘的程式與快速冪極為類似,只不過將乘換為加而已。
三、矩陣快速冪
矩陣快速冪可以用於求乙個某乙個函式值是需要從前若干項函式值線性遞推過來的函式(也稱一次多階遞推式)某一項值。
即求函式$f(n)=a_1f(n-1)+a_2f(n-2)+...+a_mf(n-m)$的$f(n)$的值。普通方法其時間複雜度為$\theta(n\times m)$。在$n$比較大時會出現超時情況。所以,我們應找乙個新的實現方法。
這個實現方法即為矩陣。
那麼首先,我們需要了解一些關於矩陣的知識。
矩陣是有定義乘法的。但是,不是所有的兩個矩陣都能相乘。
兩個矩陣$a$和$b$能夠相乘,當且僅當$a$的列數等於$b$的行數。
但是,兩個矩陣相乘法則,不是這裡所討論的。我們只需要知道如何能夠使用矩陣推出$f(n)$。
舉個例子,簡單的$fibonacci$數列,我們可以得到:
$\begin f(n) \\\ f(n-1) \end=\begin 1&1 \\\ 1&0 \end\cdot\begin f(n-1) \\\ f(n-2) \end$
一直遞推下去,就能得到乙個矩陣公式:
$\begin f(n+1) \\\ f(n) \end=\begin 1&1 \\\ 1&0 \end^n\cdot\begin f(2) \\\ f(1) \end$
再回到一般情況,我們要從
$\beginf(n)\\f(n-1)\\\ \vdots\\f(n-m)\end$推出$\beginf(n+1)\\f(n)\\\ \vdots\\f(n-m+1)\end$
其中,$f(n)$,$f(n-1)...f(n-m+1)$在原矩陣中均有出現,所以,通過構造$0$和$1$我們就可以推出。我們現在只需要算出$f(n)=a_1f(n-1)+a_2f(n-2)+...+a_mf(n-m)$。即構造矩陣的第一行為$\begina_1&a_2&...&a_m\end$。以下所有行分別只含$0$和$1$,即第$i+1$行在第$i$列的值為$1$,其他所有值全為$0$.
其中,矩陣可以進行快速冪,這樣就可以通過快速冪的$\theta(log_2n)$時間複雜度解決一次多階遞推式。
快速乘 快速冪(矩陣快速冪)
當mod乙個大數p的時候,還有進行乘法的時候可能會爆long long的時候,就用快速乘或者快速冪。參考 先上模板 快速乘 ll multi ll a,ll b,ll m return ans 快速冪 ll pow mod ll a,ll b,ll m return res 快速乘 快速冪 hdu題...
快速冪 快速乘
直接求解,需要迴圈b次。思路 將b轉化為二進位制。對應為1的次數的冪保留,只需要將保留的冪的結果進行乘積就是a b。class solution def fast self,a,b b bin b 2 res 1for i in b 1 if i 1 res res a a a return res...
快速乘,快速冪
老是忘記還是寫下來記錄一下 快速乘,和快速冪都是防止爆int,或long long,如果爆longlong可以選擇兩者結合,或者使用 int128 上網搜了還是不懂 例題 include iostream using namespace std int main b b 2 a a a m cout...