1. 程式人生 > >three(長鏈剖分)

three(長鏈剖分)

給出一棵 n 個點的無根樹,請在這棵樹上選三個互不相同的節點,使得這個三個節點兩兩之間距離相等,輸出方案數即可。n<=100000

這個題做法很多,但是 O ( n ) O(n) 長鏈剖分。。。。。。
請先自行百度。
因為長鏈剖分要節約記憶體,不能儲存每個點的DP陣列,那麼我們得用完重兒子的DP陣列之後就得繼承和修改,不能再調回去。
有一個直觀的想法就是列舉距離3個點都相等的點,這樣如果3個點都在子樹中固然好算(通過長鏈剖分求x子樹內深度為h的點的數量 f

[ x ] [ h ] f[x][h] ),可是如果要計算2個點在子樹中還有一個點在上面的話就翻車了,畢竟計算在上面的點的時候,你只能從上往下計算,這樣不僅和我們從下往上的 f
( x ) f(x)
的計算順序相反,並且你算的時候還得藉助 f ( x )
f(x)

正確的思路是列舉一定在最上面的點,即三個點的lca。
然後問題分為求在x子樹內含有兩個深度相同的節點且需求第3個點離x距離為k的方案數 h [ x ] [ k ] h[x][k] 和一個節點深度為k的 f [ x ] [ k ] f[x][k]
都可以長鏈剖分從下往上遞推,最後就拿h[x][k]和f[x][k]合併就行了。

因為每個輕兒子的長鏈都只會被父親計算一次,總複雜度是 O ( n ) O(n)
但是暴力加剪枝聽說比這跑的更快