這題其實我還不是很懂為什麼滿足了這兩個性質就一定合法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[2]=1,那麼∑a
i ∑ai
的期望就是樹的期望高度
對於bfs序相鄰的點i,i+1,
若dfn[i]>dfn[i+1],他們之間肯定換層了,a[
i+1]
=1a [i
+1]=
1若dfn[i]< dfn[i+1],他們可以換層也可以不換,a[
i+1]
=12 a[i
+1]=
12
對於dfs序相鄰的點bfn[i],bfn[i+1]
因為顯然有dep[bfn[i+1]]<=dep[bfn[i]]+1,所以若bfn[i]< bfn[i+1],有限制∑b
fn[i
+1]i
=bfn
[i]+
1a[i
]<=
1 ∑i=
bfn[
i]+1
bfn[
i+1]
a[i]
<=
1注意那個1/2的期望要滿足限制
畫一下圖可以發現如果乙個有限制的區間裡面沒有強制為1的a[
i]a [i
],那就也不會有期望1/2的a[
i]a [i
],所以維護乙個字首和用來打標記,o(n)掃一下就行了
輸出很坑…坑在**見**…
code:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using
namespace
std;
const
int maxn = 210000;
int a[maxn],to[maxn];
int s[maxn],pre[maxn],fl[maxn];
int n;
int main()
for(int i=1;i<=n;i++) a[i]=to[a[i]];
for(int i=1;i<=n;i++) to[a[i]]=i;
s[1]=s[2]=2;
for(int i=3;i<=n;i++)
if(to[i]1]) s[i]=2;
for(int i=1;i<=n;i++) pre[i]=pre[i-1]+s[i];
for(int i=2;iif(a[i]1]&&pre[a[i+1]]-pre[a[i]])
fl[a[i]+1]++,fl[a[i+1]+1]--;
int cc=0,ans=0;
for(int i=1;i<=n;i++)
double re=ans/2.0;
printf("%.3lf\n%.3lf\n%.3lf\n",re-0.001,re,re+0.001);
return
0;}
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 樹的計數
我們知道一棵有根樹可以進行深度優先遍歷 dfs 以及廣度優先遍歷 bfs 來生成這棵樹的dfs序以及bfs序。兩棵不同的樹的dfs序有可能相同,並且它們的bfs序也有可能相同,例如下面兩棵樹的dfs序都是1 2 4 5 3,bfs序都是1 2 3 4 5 現給定乙個dfs序和bfs序,我們想要知道,...