a and b and lecture rooms(
給你一棵有n個節點的樹。
有m個詢問。每次詢問給你乙個a,b。問樹上到a,b節點距離相等的點有多少個。
第一行包含整數n(1 ≤ n ≤ 10^5)。
接下來的n-1線描述了走廊。第i行(1≤ i≤≤ n - 1)包含兩個整數ai和bi(1≤ ai, bi≤ n),ai和bi有一條邊。
下一行包含整數m(1 ≤ m ≤ 10^5)-查詢數。
接下來的m行描述查詢。每行包含兩個整數a和b(1≤ a, b≤ n)輸入4
1 22 3
2 42
1 21 3輸出0
2對於每個詢問輸出有多少個節點到a和b的距離相等。
我們分析如果存在這個點,這個點一定有乙個在a-b的路徑上。
如果路徑長度為奇數就輸出0。
如果路徑長度為偶數。我們分析:
1.假設a的深度》b的深度
a~b的距離為2k,那麼這個點一定是a的第k級祖先c。
可以滿足的點就是c的子節點個數-a所在的鏈的所有節點(就是a的k-1祖先(4)的子樹大小)。
\(siz[lca(a, k)]-siz[lca(a, k-1)]\)
2.假設假設a的深度=b的深度
這個就是\(n-siz[lca(a, k-1)]-siz[lca(b, k-1)]\)
#include using namespace std;
vectorg[500005];
struct lca
dfs(root, 0);
}void dfs(int now, int father)
for(auto x: g[now])}}
int lca(int x, int y)
if(x==y) return x;
for(int k=lg[d[x]]-1; k>=0; --k)
}return fa[x][0];
}int dis(int a, int b)
int getk(int f, int k)
else
printf("%d\n", ans);}}
return 0;
}
1316 樹上的詢問(點分治)
鏈結分析 每次查詢出重心 去掉重心後的最大的聯通塊最小,保證複雜度 然後統計過重心的路徑中有沒有長度等於len的。統計時,由於必須要過重心,不能是同一棵子樹中的。可以挨個遍歷每棵子樹,然後統計即可。判斷時,用set查詢一下即可。1 include2 include3 include4 include...
BZOJ1316 樹上的詢問
給出一棵n個點的帶邊權有根樹 有q個詢問,每個詢問輸入len,判斷在樹上是否存在長度為len的路徑 直接點分治,用set儲存鏈的長度就行了 include include include include include include define maxn 11000 define inf 1 3...
樹上期望距離
設 我們分為兩個部分 兒子到父親與父親到兒子。我們先設 f i 為 i 到 fa i 的期望移動步數。顯然,分為兩種情況 對於這種情況,只需要走一步即可到達父親節點,而這種概率為 frac 長度則為 1 那麼貢獻期望長度為 frac 對於這種情況,貢獻期望長度當然為 走到兒子的步數 兒子走到 i 的...