1. 程式人生 > 實用技巧 >[性質]luogu P1232 [NOI2013]樹的計數

[性質]luogu P1232 [NOI2013]樹的計數

題面

https://www.luogu.com.cn/problem/P1232

分析

很神的一道思維題。

考慮把BFS序排序,那麼分成多少段就是樹的深度。

將DFS序投射到到BFS序上,x的DFS序大於x+1的,則必須在x,x+1之間分層,貢獻固定為1

對DFS序排序討論(BFS序要求遞減),對於相鄰的x,y:

1、x>y-1,此時可以發現y必然是x的祖先的兒子,無貢獻

2、x=y-1,可構成兄弟或父子關係,貢獻為0.5

3、x<y-1,可以發現該貢獻已經在BFS序排序中計算了,不計算該貢獻

對第三種情況用一個差分陣列維護限制即可。

程式碼

#include <iostream>
#include 
<cstdio> using namespace std; const int N=2e5+10; int n; int dfn[N],bfn[N],c[N],ans; int main() { scanf("%d",&n);ans=4;c[1]=1;c[2]=-1; for (int i=1,u;i<=n;i++) scanf("%d",&u),dfn[u]=i; for (int i=1,u;i<=n;i++) scanf("%d",&u),bfn[dfn[u]]=i; for (int i=1;i<=n;i++) dfn[bfn[i]]=i;
for (int i=1;i<n;i++) { if (dfn[i]>dfn[i+1]) ans+=2,c[i]++,c[i+1]--; if (bfn[i]+1<bfn[i+1]) c[bfn[i]]++,c[bfn[i+1]]--; } for (int i=1;i<n;i++) c[i]+=c[i-1],ans+=(!c[i]); printf("%.3lf",(double)ans/2.0); }
View Code