zoukankan      html  css  js  c++  java
  • [NOI2013]树的计数(概率期望×树的遍历)

    题目链接

    首先我们发现我们要求的就是数的期望高度,然后根据期望的线性性我们可以把它分成几层。

    观察到这个树的编号是无所谓的,我们可以给bfs序重新编号成 (1)(n),同时改变dfs序,这样不会有影响。

    又发现bfs是按层来搞的,所以我们下一步就是分层,也就是把bfs划分成几个区间,每个区间在一层。

    显然这不可能是随便分层,有一些限制。我们用一个数组来表示 (i)(i+1) 直接有没有分割,如果为 (0) 即为不确定。

    1,(1)(2) 之间一定有分隔。这很显然。

    2,假设 (d_i)(i) 在dfs序中的位置。若 (d_i>d_{i+1}) 说明dfs的过程中先遍历到 (i+1) 再遍历到 (i),而如果他们在同一层中则不可能(因为是按顺序排的),所以它们一定不在同一层中,答案加一。

    3,还有这第三个限制,也是比较难想到的。假设 (dfn_i) 是dfs序,若 (dfn_i+1<dfn_{i+1}),说明 (dfn_{i+1}) 的 深度最多比 (dfn{i}) 多1,所以 (dfn_{i})(dfn_{i+1}) 之间最多放一个分隔线,而枚举几种情况发现期间必有一条分隔线,所以这一段不得再有其他分隔线。

    最后,如果还是可填可不填的答案就加0.5。

    namespace Solve{
    	const int MAXN = 200010;
    	static int n, dfn[MAXN], bfn[MAXN], pos[MAXN], s[MAXN], d[MAXN];
    	static double ans;
    	void MAIN() {
    		read(n);
    		for (int i = 1; i <= n; i++) read(dfn[i]);
    		for (int i = 1; i <= n; i++) read(bfn[i]), pos[bfn[i]] = i;
    		for (int i = 1; i <= n; i++) dfn[i] = pos[dfn[i]], d[dfn[i]] = i;
    		s[1]++; s[2]--;
    		ans = 2.0;//注意第一个点算一层
    		for (int i = 1; i < n; i++) {
    			if (d[i] > d[i + 1]) {
    				s[i]++;
    				s[i + 1]--;
    				ans += 1.0;
    			}
    			if (dfn[i] + 1 < dfn[i + 1]) {
    				s[dfn[i]]++;
    				s[dfn[i + 1]]--;
    			}
    		}
    		for (int i = 1; i < n; i++) {
    			s[i] += s[i - 1];
    			if (s[i] == 0) {
    				ans += 0.5;
    			}
    		}
    		printf("%.3lf
    ", ans);
    	}
    } using namespace Solve;
    
  • 相关阅读:
    成功在C#和VB中将shp转换为CAD
    java 提取字符串中的数字
    java 通用文件下载 excel,pdf,word,jpg,exe,rar
    java org 写excel
    java 通用文件下载 excel,pdf,word,jpg
    重建MDB空间网格大小的工具
    redis5.0 Cluster集群搭建
    选中对象【WPF】自定义控件之依赖属性
    成员函数对象类的const和非const成员函数的重载
    设备注册Linux加载DTS设备节点的过程(以高通8974平台为例)
  • 原文地址:https://www.cnblogs.com/zcr-blog/p/13715480.html
Copyright © 2011-2022 走看看