ST求LCA的模板

2021-08-26 20:35:55 字數 1050 閱讀 7125

預處理的時間複雜度是 o(nlog2n) 查詢時間是 o(1)

#include

#include

#include

using namespace std;

const int maxn = 10010;

int rmq[2 * maxn]; // rmq陣列,就是尤拉序列對應的深度序列

struct st

for (int j = 1; j <= mm[n]; j++)}}

int query(int a,int b) // 查詢[a,b]之間最小值的下標

int k = mm[b - a + 1];

return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] : dp[b - (1

<< k) + 1][k];

}};// 邊的結構體定義

struct edge

;edge edge[maxn * 2];

int tot, head[maxn];

int f[maxn * 2]; // 尤拉序列,就是dfs遍歷的順序,長度為2

*n-1,下標從1開始

int p[maxn]; // p[i]表示點i在f中第一次出現的位置

int cnt;

st st;

void init()

void addedge(int u, int v) // 加邊,無向邊需要加兩次

void dfs(int u, int pre, int dep)

dfs(v, u, dep + 1);

f[++cnt] = u;

rmq[cnt] = dep;

}}void lca_init(int root, int node_num) // 查詢lca前的初始化

int query_lca(int u, int v) // 查詢u,v的lca編號

倍增求lca(模板)

定義 lca,最近公共祖先,是指一棵樹上兩個節點的深度最大的公共祖先。也可以理解為兩個節點之間的路徑上深度最小的點。我們這裡用了倍增的方法求了lca。我們的基本的思路就是,用dfs遍歷求出所有點的深度。f i j 陣列用來求的是距離節點i,距離2 j的祖先。可以知道,f i 0 就是它的直接父親。然...

tajan離線求LCA 模板

lca 最近公共祖先 求lca一般有用倍增的和tarjan的,tarjan是o n q 的但是必須離線。應當對於不同的題目適當選擇。tarjan演算法的主要思想 是從要求的一對點的訪問過程求來的。比如以乙個點u為根的多個小子樹內,不同小子樹內的點對的lca都是u。那麼可以dfs下去,回上去的時候用並...

倍增小結 ST 與 LCA

倍增我是真滴不會 倍增法 英語 binary lifting 顧名思義就是翻倍。能夠使線性的處理轉化為對數級的處理,大大地優化時間複雜度。ps 上次學倍增lca,沒學會,老老實實為了嚴格次小生成樹滾回來重新學 st表 n log n 的預處理與 o 1 的查詢 感性理解一下 對於每次詢問 l,r q...