二分+RMQ——洛谷 P1419 寻找段落

https://www.luogu.org/problem/show?pid=1419
我们直接二分答案;
然后只要验证是否有区间满足平均值>mid就好了;
这有一个简单的方法,就是把a[]每个数劝减去mid;
然后判断有没有一段的和>0;
这个用RMQ就好了;

#include
#define Ll long long
using namespace std;
const Ll N=1e5+5;
Ll a[N],sum,f[N];
double s[N];
int n,x,y;
bool check(double k){
    for(Ll i=1;i<=n;i++)s[i]=a[i]-k+s[i-1];
    Ll l=1,r=1;f[1]=0;
    for(Ll i=x;i<=n;i++){
        while(r>=l&&i-f[l]>y)l++;
        if(s[i]>=s[f[l]])return 1;
        while(r>=l&&s[i-x+1]1;
    }
    return 0;
}
int main()
{
    scanf("%d%d%d",&n,&x,&y);
    for(Ll i=1;i<=n;i++)scanf("%lld",&a[i]),sum+=a[i];
    double l=0,r=sum;
    while(r-l>1e-6){
        double mid=(l+r)/2.0;
        if(check(mid))l=mid;else r=mid;     
    }
    printf("%.3lf",l);
}

话说我好像好久没有写st表了

你可能感兴趣的:(二分,RMQ,单调队列)