預處理的時間複雜度是 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...