zoukankan      html  css  js  c++  java
  • 【洛谷 P1419】 寻找段落(二分答案,单调队列)

    题目链接

    开始还以为是尺取。发现行不通。
    一看标签二分答案,恍然大悟。
    二分一个(mid)(实数),把数列里每个数减去(mid),然后求前缀和,在用单调队列维护(sum[i-t ext{~}i-s])的最小值,用(sum[i])减去它,如果大于等于(0)就说明(mid)可行。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define INF 2147483647
    const int MAXN = 100010;
    const double eps = 1e-6;
    int n, s, t, head, tail;
    int a[MAXN];
    int q[MAXN];
    inline int read(){
        int s = 0, w = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
        while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0',ch = getchar();
        return s * w;
    }
    int Min = INF, Max = -INF;
    double l, r, mid, sum[MAXN];
    inline int check(double mid){
        head = tail = 0;
        for(int i = 1; i <= n; ++i)
           sum[i] = sum[i - 1] + a[i] - mid;
        for(int i = s; i <= n; ++i){
           int in = i - s;
           while(head < tail && sum[in] < sum[q[tail]]) --tail;
           q[++tail] = in;
           while(head < tail && q[head + 1] < i - t) ++head;
           if(sum[i] - sum[q[head + 1]] >= 0) return 1;
        }
        return 0;
    }
    int main(){
        n = read();
        s = read(); t = read();
        for(int i = 1; i <= n; ++i){
           a[i] = read();
           Min = min(Min, a[i]);
           Max = max(Max, a[i]);
        }
        l = Min; r = Max;
        while(r - l > eps){
          mid = (l + r) / 2.0;
          if(check(mid)) l = mid;
          else r = mid;
        }
        printf("%.3lf
    ", l);
        return 0;
    }
    
    
  • 相关阅读:
    Maven常用命令
    SpringBoot实战(十三)之缓存
    python3对数据库的基本操作
    Microsoft visual c++ 14.0 is required问题
    python3之安装mysql问题
    如何将pip更新到最新版
    Java特性之继承的应用
    人人开源之代码生成器(renren-generator)
    《你凭什么做好互联网》之思维导图归纳
    GETOBJECTOPTIONS
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/10199599.html
Copyright © 2011-2022 走看看