【NOI2013】树的计数
Description
我们知道一棵有根树可以进行深度优先遍历(DFS)以及广度优先遍历(BFS)来生成这棵树的DFS序以及BFS序。两棵不同的树的DFS序有可能相同,并且它们的BFS序也有可能相同,例如下面两棵树的DFS序都是1 2 4 5 3,BFS序都是1 2 3 4 5
现给定一个DFS序和BFS序,我们想要知道,符合条件的有根树中,树的高度的平均值。即,假如共有K棵不同的有根树具有这组DFS序和BFS序,且他们的高度分别是h1,h2,...,hk,那么请你输出
(h1+h2..+hk)/k
Input
有3行。
第一行包含1个正整数n,表示树的节点个数。
第二行包含n个正整数,是一个1~n的排列,表示树的DFS序。
第三行包含n个正整数,是一个1~n的排列,表示树的BFS序。
输入保证至少存在一棵树符合给定的两个序列。
Output
仅包含1个实数,四舍五入保留恰好三位小数,表示树高的平均值。
Sample Input
5
1 2 4 5 3
1 2 3 4 5
Sample Output
HINT
【评分方式】
如果输出文件的答案与标准输出的差不超过0.001,则将获得该测试点上的分数,否则不得分。
【数据规模和约定】
20%的测试数据,满足:n≤10;
40%的测试数据,满足:n≤100;
85%的测试数据,满足:n≤2000;
100%的测试数据,满足:2≤n≤200000。
【说明】
树的高度:一棵有根树如果只包含一个根节点,那么它的高度为1。否则,它的高度为根节点的所有子树的高度的最大值加1。
对于树中任意的三个节点a , b , c ,如果a, b都是c的儿子,则a, b在BFS序中和DFS序中的相对前后位置是一致的,即要么a都在b的前方,要么a都在b的后方。
Source
对于DFS按照BFS序重新标号,求出pos数组表示BFS序为i的点在重标号的DFS序的什么位置出现。
从1到n扫一遍所有点,即扫的时候满足BFS序从前往后。
1.如果pos[i]≤pos[i−1],那么显然i号点只能是i−1号点的下一层,对于答案的贡献为1。
2.我们知道DFS序中的一棵子树是一个连续的区间,考虑那些即可以与上一个点作为兄弟也可以作为儿子的点,它们满足了作为儿子到了单独的一层之后那一层就只有这一个点,而且作为兄弟它和它之前一个点有着共同的父亲,仔细思考后发现判定条件等价于:
令这个点为x
pos[1]⋃pos[2]⋃...⋃pos[x−1]=[1,L]⋃[R,n]
这样的点对于答案的贡献为0.5
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 1001000 10 #define llg int 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,dfn[maxn],bfn[maxn],p_bfn[maxn],pos[maxn]; 13 llg l,r,bj[maxn]; 14 void init() 15 { 16 cin>>n; 17 for (llg i=1;i<=n;i++) scanf("%d",&dfn[i]); 18 for (llg i=1;i<=n;i++) scanf("%d",&bfn[i]),p_bfn[bfn[i]]=i; 19 for (llg i=1;i<=n;i++) dfn[i]=p_bfn[dfn[i]]; 20 for (llg i=1;i<=n;i++) pos[dfn[i]]=i; 21 l=2;r=n+1; 22 bj[1]=bj[2]=1; 23 } 24 25 int main() 26 { 27 yyj("a"); 28 init(); 29 double ans=2; 30 for (llg i=3;i<=n;i++) 31 { 32 if (pos[i]<pos[i-1]) 33 ans++; 34 if (pos[i]-1==pos[i-1]) 35 { 36 if (n-r+1+l==i-1) ans+=0.5; 37 } 38 39 bj[pos[i]]=1; 40 while (bj[l+1]) l++; 41 while (bj[r-1]) r--; 42 } 43 printf("%.3lf",ans); 44 return 0; 45 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架