• BZOJ3244/UOJ122 [Noi2013]树的计数


    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

     

    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

    3.500

    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的后方。

     

    正解:分析

    解题报告:

      参见博客:LCF大爷

           llg大爷

           一篇详细的博客

      

     

    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    using namespace std;
    typedef long long LL;
    const int MAXN = 200011;
    int n,dfn[MAXN],bfn[MAXN],sum[MAXN],c[MAXN],p_bfn[MAXN],pos[MAXN];
    double ans;
    
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void work(){
    	n=getint(); sum[1]=1;//1必然被分为1段
    	int tot=0; for(int i=1;i<=n;i++) dfn[i]=getint();
    	for(int i=1;i<=n;i++) bfn[i]=getint(),p_bfn[bfn[i]]=i;
    	for(int i=1;i<=n;i++) dfn[i]=p_bfn[dfn[i]];
    	for(int i=1;i<=n;i++) pos[dfn[i]]=i;
    	for(int i=1;i<n;i++) if(pos[i]>pos[i+1]) sum[i]++,c[i]++,c[i+1]--;//必然分了一段y
    	for(int i=2;i<=n;i++) sum[i]+=sum[i-1]; ans=sum[n];//前缀和
    	for(int i=1;i<n;i++) if(dfn[i]<dfn[i+1] && sum[dfn[i+1]-1]-sum[dfn[i]-1]) c[dfn[i]]++,c[dfn[i+1]]--;
    	for(int i=1;i<n;i++) { tot+=c[i]; if(tot==0) ans+=0.5; }
    	ans++;//第一层
    	printf("%.3lf
    ",ans-0.001);
    	printf("%.3lf
    ",ans);
    	printf("%.3lf",ans+0.001);
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

     
  • 相关阅读:
    利用QObject反射实现jsonrpc
    使用libuv实现生产者和消费者模式
    std::function赋值的几种方法
    Qt postEvent
    Qt由pcm数据生成wav文件
    Qt websocket协议的实现
    Python中json.dump() 和 json.dumps()的区别
    Appium环境搭建(Mac)
    Mac上搭建Python集成环境
    Mac OS终端利器iTerm2(完美替代bash)
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6388908.html
Copyright © 2020-2023  润新知