1、快速冪函數
快速冪是用於解決相似 $a^b$ $mod$ $p$值類型的問題的。使用普通的方法是從$1$循環至$b$,再逐次累乘,逐次取模。但這種方法對於$b$很大的時候卻可能會超時。那麼,這時候咱們就須要使用快速冪了。優化
快速冪是基於如下式子:spa
若$b$ $mod$ $2=1$,則$a^b=a^\frac{b}{2}\times a^\frac{b}{2}\times a$code
若$b$ $mod$ $2=0$,則$a^b=a^\frac{b}{2}\times a^\frac{b}{2}$blog
這樣,咱們便經過分治將一個大問題變爲兩個小問題,再逐項計算,並取模。ci
另外,再加上兩個邊界條件:class
$a^0=1$,$a^1=a$es7
例以下面的例子:循環
$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,int b){ if(b==0)return 1; if(b==1)return a; int res=_pow(a,b/2); if(b%2)return res*res*a; return res*res; }
2、快速乘
快速乘常與快速冪結合在一塊兒。當模數$p$過大時,乘起來可能會超過$long$ $long$的範圍。因此,咱們也能夠藉助快速冪的思想在中間優化一下乘法。
注意到乘法$a\times b$能夠轉化爲$\underbrace{a+a+...+a}_{b}$,因此咱們也可以經過分治方法將其轉化。
例以下面的例子:
$3\times7=3\times3+3\times3+3=(3\times1+3\times1+3)+(3\times1+3\times1+3)+3$
其中,全部的式子也能夠進行計算,複雜度依然爲$\Theta(log_2b)$。
快速乘的程序與快速冪極爲相似,只不過將乘換爲加而已。
3、矩陣快速冪
矩陣快速冪能夠用於求一個某一個函數值是須要從前若干項函數值線性遞推過來的函數(也稱一次多階遞推式)某一項值。
即求函數$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{bmatrix} f(n) \\\ f(n-1) \end{bmatrix}=\begin{bmatrix} 1&1 \\\ 1&0 \end{bmatrix}\cdot\begin{bmatrix} f(n-1) \\\ f(n-2) \end{bmatrix}$
一直遞推下去,就能獲得一個矩陣公式:
$\begin{bmatrix} f(n+1) \\\ f(n) \end{bmatrix}=\begin{bmatrix} 1&1 \\\ 1&0 \end{bmatrix}^n\cdot\begin{bmatrix} f(2) \\\ f(1) \end{bmatrix}$
再回到通常狀況,咱們要從
$\begin{bmatrix}f(n)\\f(n-1)\\\ \vdots\\f(n-m)\end{bmatrix}$推出$\begin{bmatrix}f(n+1)\\f(n)\\\ \vdots\\f(n-m+1)\end{bmatrix}$
其中,$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)$。即構造矩陣的第一行爲$\begin{bmatrix}a_1&a_2&...&a_m\end{bmatrix}$。如下全部行分別只含$0$和$1$,即第$i+1$行在第$i$列的值爲$1$,其餘全部值全爲$0$.
其中,矩陣能夠進行快速冪,這樣就能夠經過快速冪的$\Theta(log_2n)$時間複雜度解決一次多階遞推式。