演算法學習筆記 倍增

2022-07-01 19:33:07 字數 1699 閱讀 6522

倍增是一種非常重要的思想,在 acm/oi 中有著豐富的應用。

倍增的本質可以表述為,對於一種操作\(f(x)\),通過計算\(f(x),f^2(x),f^4(x),\cdots,f^(x)\)來加速求解\(f^n(x)\)。假設\(f(x)\)的時間複雜度為\(o(1)\),那麼直接計算\(f^n(x)\)的時間複雜度為\(o(n)\),而通過倍增的方法,則可以加速到\(o(\log n)\)。

快速冪是倍增最常見的應用場景。所謂快速冪,指的是快速求解數\(x\)在模\(m\)意義下的冪\(x^y\mod m\)。

比較直接的想法是遞迴進行求解。很容易得到下面的遞迴式:

\[x^y=\left\

&1 & y=0 \\

&(x^})^2 & y\text \\

&(x^})^2\cdot x & y\text\end\right.

\]模板題:洛谷p1226

注意使用long long保證資料不溢位

code(c++)
#include using namespace std;

using ll = long long;

int qpow(int b, int p, int k)

// 求 b^p mod k

int main()

遞迴方法對於快速冪已經足夠,但其缺乏足夠的普適性,無法推廣到更加一般性的問題。

與遞迴方法相比,迭代方法的思想更加貼近倍增方法的本質。利用\(x^y=x^^k c_i2^i}\),我們可以從\(x^1,x^2,\cdots,x^\)來計算出\(x^y\),而這些數值本身是可以通過反覆進行平方運算在\(o(k)=o(\log y)\)的時間內求得的。這裡我們需要得到乙個非負整數的二進位制表示(從低位到高位),只需要不斷除以2取餘即可。

模板題:洛谷p1226

注意使用long long保證資料不溢位

code(c++)
using ll = long long;

int qpow(int a, int b, int k)

// 求 b^p mod k

int main()

將快速冪中的乘法運算替換為加法運算,我們就可以得到快速乘的演算法,也即用\(o(\log n)\)次加法運算來實現乘\(n\)的操作。

快速乘模板**:

// 迭代實現

inline ll ksc(ll x, ll y, ll mod)

// o(1)快速乘

typedef long long ll;

typedef unsigned long long ull;

typedef long double lb;

//**壓縮

inline ll ksc(ull x, ull y, ll p)

將快速冪中的底數改為乙個方陣,並將整數乘法改為矩陣乘法,我們就可以得到矩陣快速冪的演算法。

如果把\(f(x)\)看作是求取\(x\)的父節點,那麼\(f^n(x)\)就可以是看成求取\(x\)第\(n\)代的祖先節點。倍增法求lca的關鍵就是用倍增方法來快速求取\(f^n(x)\)。

稀疏表是一種用於rmq(區間最值查詢)的資料結構。稀疏表的構建同樣使用了倍增的思想。

字尾陣列倍增演算法學習筆記

字尾陣列 suffix array 簡稱sa陣列裡面儲存的是字串s從小到大或從大到小的所有字尾。用處後續補,還不太清楚作用。首先牢牢記住sa i 意思是排第 i 的字尾是誰,而rank i 代表字尾 i 排第幾。然後先放上盜來的,其實這個演算法思路還是很簡單的,難的地方在於編碼。如果不了解基數排序的...

演算法 學習筆記

1.輸入輸出演算法至少有乙個或多個輸出 2.有窮性 3.確定性 4.可行性 1.正確性a.演算法程式沒有語法錯誤 b.演算法程式對於合法的輸入資料能夠產生滿足要求的輸出結果 c.演算法程式對於非法的輸入資料能夠得出滿足規格說明的結果 d.演算法對於精心選擇的,甚至刁難的測試資料都有滿足要求的輸出結果...

演算法學習筆記

複雜度分析 1.只關注迴圈次數最多的一行 2.總複雜度等於量級最大 的複雜度 3.巢狀 的複雜度等於巢狀 內外複雜度的乘積 單鏈表結構和順序儲存結構的優缺點 儲存分配方式 時間效能 空間效能 單鏈表結構 用一組任意的儲存單元存放線性表元素 查詢 o n 插入和刪除 找到某位置的指標後,插入和刪除的時...