題目位址
題意簡述:樹上任意兩點 \(a,b\),從 \(a\) 隨機遊走到 \(b\) 的期望步數。\(n \le 10^5\)。
應該是乙個經典題,為什麼只有洛谷上能找到。
令根為終點,注意到每個點的轉移方向只有向父親或向兒子兩種,可以將期望的狀態定義設計為轉移向一邊的期望:設 \(f[u]\) 表示 \(u->fa\) 的期望步數,即從 \(u\) 向上走一步的期望步數。則有:
\[f[u] = \frac + \frac
\](其中 \(d_u\) 表示 \(u\) 的度數)
移項,則有:
\[f[u] = d_u + \sum f[v]
\]特別的,假設根為 \(x\),有 \(f[x]=0\)。
令\(g(x)\)表示根為\(x\)(即終點為 \(x\))時的答案,\(dep'[u]\) 表示 \(u->x\) 的期望步數。根據定義:\(g(x)=\sum dep'[u]\),其中:\(dep'[u]=dep'[fa]+f[u]\)。進一步我們可以發現,\(g(x)=\sum f[u]*sz_u\) 其中 \(sz_u\) 表示 \(u\) 的子樹大小。
由於根 \(x\)可以是 \(1 \sim n\) 的任意乙個點,所以我們需要算出 \(g(x),1 \le x \le n\)。於是我們可以寫乙個換根dp。
假設 \(u\) 是當前的根,\(v\) 是 \(u\) 的兒子且是下乙個根。可以發現根從 \(u\) 換到 \(v\),\(f[\ ]\) 陣列中僅有 \(f[u]\) 和 \(f[v]\) 發生了改變,同樣的,只有 \(sz_u\) 和 \(sz_v\) 發生了改變。具體的:
\[f[u] = sum-f[v],\ f[v]=0
\](其中 \(sum = \sum d_u\))
所以,\(u\) 對答案的貢獻從 \(0\) 變成了 \((sum-f[v])(n-sz_v)\),而 \(v\) 對答案的貢獻從 \(f[v]*sz_v\) 變成了 \(0\)。具體的:
\[g(v)=g(u)+(sum-f[v])(n-sz_v)-f[v]*sz_v
\]用兩遍 \(dfs\) 即可實現,時間複雜度 \(o(n)\)。
talk is cheap.show me the code.
#include#define int long long
using namespace std;
inline int read()
while(ch>='0'&&ch<='9')
return x * f;
}const int n = 100007, mod = 998244353;
int n,cnt,sum;
int f[n],g[n],sz[n],deg[n];
int head[n];
struct edge edge[n<<1];
inline void add(int u,int v)
inline void add(int &x,int y)
inline void dec(int &x,int y)
void dfs1(int u,int fa) }}
void dfs2(int u,int fa) }}
int pow(int x,int y)
return res;
}signed main()
{ n = read();
for(int i=1;i經典題,沒啥好說的。
洛谷 3398 倉鼠找sugar
題目描述 小倉鼠的和他的基 me i mei mei 友 zi sug ar zi sugar zi su gar住在地下洞穴中,每個節點的編號為1 n1 n 1n。地下洞穴是乙個樹形結構。這一天小倉鼠打算從從他的臥室 a a a 到餐廳 b b b 而他的 同時要從他的臥室 c c c 到圖書館 ...
洛谷3398 倉鼠找sugar
小倉鼠的和他的基 mei 友 zi sugar住在地下洞穴中,每個節點的編號為1 n。地下洞穴是乙個樹形結構。這一天小倉鼠打算從從他的臥室 a 到餐廳 b 而他的 同時要從他的臥室 c 到圖書館 d 他們都會走最短路徑。現在小倉鼠希望知道,有沒有可能在某個地方,可以碰到他的 小倉鼠那麼弱,還要天天被...
洛谷P3398 倉鼠找sugar
裸的lca。對於每次詢問,設a,b的lca為a,c,d的lca為b,分兩種情況討論 1 a與b的深度相同,此時二人相遇的充要條件為a b,即四個點的最近公共祖先相同。2 a與b深度不同,設a的深度大於b的深度,若二人相遇,則c或d與a的lca一定為a。include include define m...