数学题一个
首先经过计算,我们可以得知公式:
∵ s i = ∏ i = 1 n ( 1 − p k ) \because s_i=\prod_{i=1}^n(1-p_k) ∵si=i=1∏n(1−pk)
又 ∵ f i = ∑ k = 1 i p k 1 − p k \text{又}\because f_i=\sum_{k=1}^i \dfrac{pk}{1-pk} 又∵fi=k=1∑i1−pkpk
∴ 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)=sl−1srfr−fl−1
就这样,立马想到了暴力,时间复杂度为 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;//完结,撒花!
}