PE 567

萌萌哒博主开始做PE啦!
之后的PE应该会良心给答案。
这次的是75.44817535。
感觉被卡精度卡得昏天黑地。
注意到JA的前缀和是

i=1nj=1n(ij)2ij

JB的前缀和是
i=1nj=1n1(ij)j

两个都要交换i和j。分开考虑。
第一个
j=1nni=1(ij)2ij


Fi=i=1n(ij)2i

将上面的那个组合数拆成
(i1j1)+(ij1)

我们可以方便地得到
FiFi1=(n+1i)2n

第二个式子比较trival,我们将i,j调换顺序后会出现一个
i=1n1(ij)

冷静一下,这不是小学奥数中的裂项吗?暴力裂项大法好!
之后的式子就不写了,留给读者自己推导吧(其实是博主觉得写Latex太麻烦了)
当然注意特判j=1的情况,这个是一个调和级数数列之和,没办法裂项。
这样计算就是线性了。但是精度会炸飞。我们可以将乘除在log下计算,加减的时候exp回去。当然不要试图预处理阶乘的对数,你会MLE+炸精度,正确姿势是递推。
附代码。

#include <bits/stdc++.h>

using namespace std;

int n;

int main()
{
    scanf("%d", &n);
    long double ans = 0, tmp = 2 - 1 / pow(2.0, n), f = -log(2.0) * n;
    for(int i = 1; i <= n; i++) {
        f = f + log(n + 2 - i) - log(i);
        tmp -= exp(f);
        ans += tmp / i;
    }
    f = -log(n);
    for(int i = 2; i <= n; i++) {
        ans += 2.0 / (i - 1) - exp(f);
        f = f + log(i - 1) - log(n - i + 1);
    }
    printf("%.15lf\n", (double) ans + 1.0 / n);
    return 0;
}

Thread里的众人的智慧真是无穷啊。。。
大众做法是考虑JA(n)-JB(n)在n很大的时候这个值十分的小(否则为什么会有PE 568),所以说卡一发精度就暴力过了。
get了几个公式:
这里是一堆干掉组合数的式子及证明
这里是第三个式子的证明

r>=012r+1(n+12r+1)=i=0n2ii+1

r>=112r(n+12r)=i=0n2i1i+1

k=1n1k(nk)=12nk=1n2kk

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值