lca指最近公共祖先。他有許多的求法和應用。
首先最簡單的:跳到同一深度後,再一起向上跳,跳到同一節點為止。
這個方法時間複雜度最壞為\(o(n)\),如果不是乙個老善人是不會讓你過的。
如何優化這個方法呢?我們可以試試倍增,每次上跳多個節點,這樣時間複雜度就只有\(\log n\)了。
上p3379**,可以結合**食用:
#includeusing namespace std;
int n,q,head[500001],father[500001][21],tot,h[500001]= ,s;
inline void read(int &x)
while(chc>='0'&&chc<='9')
x=dat*oko;
}struct tu edge[1000001];
void insert(int x,int y)
void dfs(int x,int fa) }}
int lca(int x,int y)
} if(x==y)return x;
int p=0;
for(int i=20;i>=0;i--)
} return father[y][0];
}int main() \)為\(d_x+d_y-2\times d_\)
2.樹上區間加,附查詢
如果動態就要樹剖或lct,但靜態可用樹上差分。
具體在\(x,y\)都加,\(lca\)位置將其抵消。
最近公共祖先(LCA) 學習筆記
顧名思義,就是兩個結點的最近公共父結點 這裡運用了倍增的思路,當你想要乙個個的往上遞增時,複雜度很高,可以把要遞增的數量換成二進位制表示 因為任意乙個數都可以由二進位制數相加得到 比如11,可以由 2 3 8,2 1 2,2 0 1,相加而成 所以11這個數可以先加8,在加2,在加1得到 這裡有兩個...
最近公共祖先 LCA 最近公共祖先
直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...
最近公共祖先 最近公共祖先(LCA)
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...