题面
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); }