那么问题就变成如何查找是否存在这样的一个平均值了。假设要查找的平均值mean,我们只要查找
∑
a
[
i
]
a
[
i
]
+
a
[
i
+
f
]
\sum_{a[i]}^{a[i]+a[i+\rm f]}
∑a[i]a[i]+a[i+f]的值或者
∑
a
[
i
]
a
[
i
]
+
a
[
i
+
f
]
\sum_{a[i]}^{a[i]+a[i+\rm f]}
∑a[i]a[i]+a[i+f]再加上后面的数是不是大于
m
e
a
n
∗
f
\rm mean*\rm f
mean∗f。显然用前缀和会方便很多。另外加上后面的数时,只要考虑后面的数是不是比平均值大就行了。不过需要找的平均值的 有个注意点,后面的数是要减去
m
e
a
n
\rm mean
mean的,这样才能算的是平均值,需要很轻度的推算。
代码
#include<iostream>#include<cstdio>usingnamespace std;constint MAXN =100000+5;int N, F;double num[MAXN];double sum[MAXN];double rmaxsum[MAXN];double l =9999999, r =0;boolqualify(double tans){for(int i = N; i >=1; i--)
rmaxsum[i]=max(num[i]- tans, rmaxsum[i +1]+ num[i]- tans);for(int i =1; i <= N - F +1; i++){if(sum[i + F -1]- sum[i -1]>= F * tans)returntrue;if(sum[i + F -1]- sum[i -1]- F * tans + rmaxsum[i + F]>=0)returntrue;}returnfalse;}intmain(){
cin >> N >> F;for(int i =1; i <= N; i++){scanf("%lf",&num[i]);
sum[i]= sum[i -1]+ num[i];
r =max(r, num[i]);
l =min(l, num[i]);}while(l < r -0.0001){double mid =(r + l)/2;if(qualify(mid))
l = mid;else
r = mid;}
cout <<int(r *1000)<< endl;return0;}