倍增是把時間複雜度為o(n
)o(n)
o(n)
的乙個操作變為o
(log2
n)
o(\log_2n)
o(log2n
)的操作。
它與分治的思想類似,時間複雜度也類似。
它們的區別如下:
分治是將乙個問題分成若干個子問題,最後的答案由子問題的答案合併得到。
倍增是將乙個需要執行多次的操作分解,操作的結果直接由兩個子操作的結果得到。
最常見的例子就是在樹上倍增。
每個詢問要求節點x
xx向上跳s
ss次到達的節點編號。
若每次暴力向父親節點跳,一共跳s
ss次,時間複雜度特別大。
這時就要使用倍增。
維護每個節點向上跳可到達的節點編號。
設f [i
][j]
f[i][j]
f[i][j
]表示節點i
ii向上跳2
j2^j
2j次到達的節點編號。
所有的f[i
][0]
f[i][0]
f[i][0
]自然就為fat
her[
i]
father[i]
father
[i](i
ii的父親節點),其餘的如何轉移?
我們可以發現,向上跳2
j2^j
2j次就相當於是先向上跳2j−
12^
2j−1
次,再向上跳2j−
12^
2j−1
次。於是我們不難得到轉移方程:
f [i
][j]
=f[f
[i][
j−1]
][j−
1]
f[i][j]=f[f[i][j-1]][j-1]
f[i][j
]=f[
f[i]
[j−1
]][j
−1]
void
dfs(
int i,
int fa)
怎麼跳?
類似十進位制轉二進位制的方式,從大到小列舉j
jj,如果s≥2
js≥2^j
s≥2j
就把x
xx跳到f[x
][j]
f[x][j]
f[x][j
],並且把s−2
js-2^j
s−2j
。
for
(j=log
(n);j>=
0;j--
)}
可以用倍增實現的還有很多,如樹上最大值、樹上兩點的最近公共祖先(lca)等,對解題有很大幫助。
相信你已經對倍增了解不少了。要時刻記得,演算法是死的而人是活的,必須學會靈活變通,找到題目突破口,才能順利解題!
python 資料結構與演算法 倍增思想
倍增是一種思想,每次將考慮的範圍擴大或減少一倍從而達到加速的效果,將某一步的o n 優化到o logn 也就是一種自底向上的二分 如快速冪 顧名思義就是一倍一倍的增加。舉個例子你每次可以跳2的k次方步。現在你要跳到距離7步的地方。跳8步 跳過了 不跳 跳4步 沒跳到 跳 跳2步 沒跳到 跳 跳1步 ...
知識點 2 6 倍增思想
總目錄 2 演算法基礎 2.6 倍增思想 前言 倍增通常和二分一起介紹,共同點在於 它們都能神奇地將原本複雜度為 n 的過程下降到 log n,對於大型資料而言,這種效率的提高是顯而易見的。子目錄列表 1 二進位制與倍增 2 例題 3 應用 2.6 倍增思想 1 二進位制與倍增 眾所周知,二進位制與...
2022 2 25 倍增思想和ST表
倍增 將線性級轉換成對數級,降低時間複雜度 只考慮二的整數冪次,縮小查詢範圍。運用 1.快速冪 算n的m次方,log n 遞推法 int ans 1 while n 2.rmq問題 n個數字m次詢問,每次 l,r 中最大值 運用st表,預處理 o nlogn 查詢o 1 想法是將每次要查詢的區間的最...