倍增 思想與操作

2022-05-29 20:27:17 字數 1503 閱讀 3274

倍增是把時間複雜度為o(n

)o(n)

o(n)

的乙個操作變為o

(log⁡2

n)

o(\log_2n)

o(log2​n

)的操作。

它與分治的思想類似,時間複雜度也類似。

它們的區別如下:

分治是將乙個問題分成若干個子問題,最後的答案由子問題的答案合併得到。

倍增是將乙個需要執行多次的操作分解,操作的結果直接由兩個子操作的結果得到。

最常見的例子就是在樹上倍增。

每個詢問要求節點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 想法是將每次要查詢的區間的最...