BZOJ 3244 Noi2013 樹的計數

2022-05-19 10:55:43 字數 2821 閱讀 7720

傳送門

神仙題...

和樹的深度有關,由於 $bfs$ 序的性質,顯然可以通過把 $bfs$ 序分成若干段來求出深度,每一段就對應某一深度從左到右的所有節點,那麼如果確定了分的段數就確定了樹的深度(分的段數 $+1$)

為了方便,先把 $bfs$ 序變成從 $1$ 到 $n$ 的序列, $dfs$ 序當然也要隨著變一下

考慮每個位置是否可以分段,無非 $3$ 種情況:

$1.$ 此位置必須分,那麼對樹的深度貢獻就是 $1$

$2.$ 此位置不能分,那麼貢獻就是 $0$

$3.$ 此位置可分可不分,那麼貢獻就是 $0.5$(此位置分的樹的方案數和不分的樹的方案數是一樣的,如果分貢獻 $1$,不分貢獻 $0$,那麼平均貢獻就是 $0.5$)

考慮用 $bfs$ 序和 $dfs$ 序之間的關係求出每個位置的限制,設節點 $i$ 的 $bfs$ 序為 $bfn[i]$,$dfs$ 序為 $dfn[i]$

對於 $bfs$ 序連續的兩點 $x,y=x+1$(此時已經按 $bfn$ 重新標號了),如果 $dfn[x]>dfn[y]$ ,說明 $y$ 在 $x$ 的下一層

大概圖長這樣:

可以發現只有這種情況才會出現 $dfn[x]>dfn[y]$ 的情況,因為如果 $x$ 和 $y$ 在同一層那麼顯然 $y$ 會更晚被 $dfs$ 到

所以如果 $dfn[x]>dfn[x+1]$,那麼 $x$ 和 $x+1$ 之間必須分層

那麼如果 $dfn[x]

可能有兩種情況,$x$ 沒有兒子, $x+1$ 是 $x$ 的兄弟;$x+1$ 是 $x$ 的兒子,還是沒辦法確定,而且發現不管是哪種情況都不會對之後的序列產生影響,這保證了無法確定的位置貢獻是 $0.5$(這個位置不管切不切方案數都是一樣的)

對於 $dfs$ 序連續的兩點 $x,y$,情況比較多

如果 $x>y-1$ ($bfn[x]>bfn[y-1]$),那麼說明 $y$ 是 $x$ 某個祖先的兒子:

對限制並沒有影響

如果 $x==y-1$,那麼 $y$ 作為 $x$ 兄弟或者兒子都是合法的

所以仍然無法確定貢獻,但是同樣可以發現不管是哪種情況對後面的序列都沒有影響(

裡後面節點可以接到 $y$ 下面或者作為 $y$ 的下乙個兄弟)

但是第三種情況有點意思:$x

說明 $y$ 一定是 $x$ 的第乙個兒子:

那麼就是說,編號從 $x$ 到 $y-1$ 的所有節點深度差不超過1

而且可以發現,如果有分割那麼在之前就被計算過了(一定存在 $k$ 使得 $dfn[x+k]>dfn[x+k+1]$ , $x+k \in [x+1,y-1]$ )

所以對於 $x

這個限制可以用乙個差分陣列維護

最後剩下的都不能確定了,貢獻就是 $0.5$

最後乙個問題,這些限制是必要的,但是,充分嗎?

感性理解一下,很充分,如果懷疑的話打個暴力拍它幾個小時,發現沒問題,所以是充分的...

並不會證明限制充分 $qwq$

**很短,但是並不好想...

設 $pos[i]$ 表示 $dfn$ 為 $i$ 的節點(其實就是 $dfn$ 的反陣列)

那麼對於前面最後乙個限制,$x

注意一開始那些一定要分割的位置已經算過就不會再產生 $0.5$ 的貢獻了

還有第乙個節點一定單獨要分一層

#include#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;inline

intread()

while(ch>='

0'&&ch<='

9')

return x*f;

}const

int n=2e6+7

;int

n;double

ans;

int dfn[n],pos[n],sum[n];//

sum是差分陣列

//dfn是節點的dfs序,pos是dfn的反陣列,所以有 pos[dfn[i]]=i,dfn[pos[i]]=i

inline void mark(int x,int y) //

打差分標記

intmain()

int now=0

;

for(int i=1;i0 : 0.5);//

如果這個位置不確定則貢獻為0.5

//注意上一行i不取n,因為切的位置只有n-1個

ans+=1;//

深度等於分的段數+1

printf("

%.3lf\n%.3lf\n%.3lf

",ans-0.001,ans,ans+0.001);//

bzoj上要這樣輸出...

return0;

}

BZOJ3244 NOI2013樹的計數

給定一棵 n n 200000 個節點的樹的 df s bf s 序,求所有滿足要求的樹的平均深度。考慮到 bf s 序的性質,bf s 在前的點的深度一定小於等於後面的點。所以我們考慮根據 bf s 序計算答案。首先根據 bf s 序給樹上的點重編號,按 bf s 序的先後編成 1,2,n 考慮相...

BZOJ3244 NOI2013 樹的計數

我們知道一棵有根樹可以進行深度優先遍歷 dfs 以及廣度優先遍歷 bfs 來生成這棵樹的dfs序以及bfs序。兩棵不同的樹的dfs序有可能相同,並且它們的bfs序也有可能相同,例如下面兩棵樹的dfs序都是1 2 4 5 3,bfs序都是1 2 3 4 5 現給定乙個dfs序和bfs序,我們想要知道,...

BZOJ3244 Noi2013 樹的計數

這題其實我還不是很懂為什麼滿足了這兩個性質就一定合法qaq 先將所有點按其bfs序重新標號 我們令dfn i 表示i的dfs序,bfn i 表示dfs序為i的點的bfs序 考慮怎麼計算答案,我們令dep i 表示點i所在樹中的層數,那麼對dep i 做個差分,a i a i a i 1 a 1 a ...