码迷,mamicode.com
首页 > 其他好文 > 详细

【Luogu】P1419寻找段落(单调队列)

时间:2018-01-29 11:35:05      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:pre   ring   最大   --   limit   body   etc   def   单调队列   

  题目链接

  不知为何状态突然奇差无比,按说这题本来应该是水题的,但不仅不会做,还比着题解爆零五次

  二分平均值(想到了),单调队列维护最大区间和(想到了但是不会,???为什么我不会???)

  

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cstdlib>
#define maxn 200020
#define eps 1e-6
using namespace std;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch==-)    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-0;
        ch=getchar();
    }
    return num*f;
}

int q[maxn];
double sum[maxn];
int s[maxn],h,t;
int n,lim,lia;

inline double calc(int x,int y){
    return sum[y]-sum[x-1];
}

bool check(double limit){
    h=1,t=0;
    for(int i=1;i<=n;++i){
        if(i>=lim){
            while(h<=t&&sum[i-lim]<sum[s[t]])    t--;
            s[++t]=i-lim;
        }
        while(h<=t&&s[h]<i-lia)    h++;
        if(h<=t&&sum[i]-sum[s[h]]>=0)    return 1;
    }
    return 0;
}

int main(){
    n=read(),lim=read(),lia=read();
    for(int i=1;i<=n;++i)    q[i]=read();
    double l=-10000,r=10000;double ans=0;
    while(r-l>eps){
        double mid=(l+r)/2;
        for(int i=1;i<=n;++i)    sum[i]=sum[i-1]+q[i]-mid;
        if(check(mid)){
            l=mid;
            ans=mid;
        }
        else    r=mid;
    }
    printf("%.3lf",ans);
    return 0;
}

 

【Luogu】P1419寻找段落(单调队列)

标签:pre   ring   最大   --   limit   body   etc   def   单调队列   

原文地址:https://www.cnblogs.com/cellular-automaton/p/8375947.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!