hdu 5425 Rikka with Tree II

题解:
1.因为只需要保存小数点后6位,所以并不需要把1e5这么大的数全部枚举出来
2.double的表示长度也只有2 ^ 1000,所以不能直接把2 ^ 100000算出来,要提前约分
3.double的精度为15–16位,作为常识可以顺便记下来
4.最多需要枚举最大的100个数,因为10e5 * 10e5 * 10e5 / 2 ^ 100 约= 1 / 1e15,几乎再小的数枚举也对结果造成不了影响
总结:
1.虽然解题的时候讲究弱化或者加强条件,但是如果实在想不出来的话,可以在重新考量某些忽略的条件,也许就是解题关键!
2.如果连WA几次,就必须不能再考虑这个题目了,放空自己,不纠结与细节,等过一段时间,回头再看这个题目的时候,就可以从宏观的思考这个问题了

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define MAXN 100005
vector<int>vec[MAXN];
queue<int>q;
int n,d[MAXN];
inline double f(double a,double b)
{
    return a * b / (a + b);
}
double solve()
{
    double ans = 0;
    for(int i = n - 1;i >= max(n - 100,0);i--)
        for(int j = n - 1;j > i;j--)
            ans += f(d[i],d[j]) / (pow(2.0,n - i) - (n + 1) / pow(2.0,i));
    return ans;
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        for(int i = 0;i <= n;i++)vec[i].clear();
        for(int i = 1;i < n;i++)
        {
            int u;
            scanf("%d",&u);
            vec[u - 1].push_back(i);
        }
        d[0] = 1;
        q.push(0);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int i = 0;i < vec[u].size();i++)
            {
                int v = vec[u][i];
                d[v] = d[u] + 1;
                q.push(v);
            }
        }
        sort(d,d + n);
        double ans = solve();
        printf("%.6f\n",ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值