P5242 题解

数学题一个

题目传送门

首先经过计算,我们可以得知公式:

∵ s i = ∏ i = 1 n ( 1 − p k ) \because s_i=\prod_{i=1}^n(1-p_k) si=i=1n(1pk)

又 ∵ f i = ∑ k = 1 i p k 1 − p k \text{又}\because f_i=\sum_{k=1}^i \dfrac{pk}{1-pk} fi=k=1i1pkpk

∴ a n s ( i , j ) = s r s l − 1 f r − f l − 1 \therefore ans(i,j)=\frac{sr}{sl-1}fr-f_{l-1} ans(i,j)=sl1srfrfl1

就这样,立马想到了暴力,时间复杂度为 O ( n 2 ) O(n^2) O(n2),但是突然想到了可以用尺取法来优化。

就这样,它变成了 O ( n ) O(n) O(n) ,皆大欢喜!


Coding Time: \text{Coding Time:} Coding Time:

#include<bits/stdc++.h>

using namespace std;

#define gc getchar()

inline int read()//快读
{
    int x=0; 
    bool sgn=0;
    char s=gc;
    while(!isdigit(s))sgn|=s=='-',s=gc;
    while(isdigit(s))x=(x<<1)+(x<<3)+(s-'0'),s=gc;
    return sgn?-x:x;
}

int n;
long double num[1008611], cdy = 1.0, wzy, ans;//你想见祖宗吗?

int main() 
{
    n=read();
    for (register int i = 1, x; i <= n; ++i) 
    {
        x=read();
        num[i] = ((long double)x / 1000000.0);
        ans = max(ans, num[i]);
    }
    for (register int i = 1, tail = 1; i <= n; ++i) 
    {
        while (tail <= n && cdy * wzy < cdy * (1.0 - num[tail]) * (wzy + num[tail] / (1.0 - num[tail]))) 
        {
            cdy *= (1.0 - num[tail]);
            wzy += num[tail] / (1.0 - num[tail]);
            ++tail;
        }
        ans = max(ans, cdy * wzy);
        cdy /= (1.0 - num[i]);
        wzy -= num[i] / (1.0 - num[i]);
    }
    printf("%d\n", (int)(ans * 1000000));
    return 0;//完结,撒花!
}

AC 记录


注:此文章灵感来源自kimi0705的博客
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值