[性質]luogu P1232 [NOI2013]樹的計數
阿新 • • 發佈:2020-10-21
題面
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> #includeView Code<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); }