zoukankan      html  css  js  c++  java
  • luoguP1419 寻找段落(二分答案+单调队列)单调队列DP求在区间[l,r] 中长度至少为 m 的最大平均值

    模板:单调队列DP求在区间([l,r]) 中长度至少为 (m) 的最大平均值

    题目链接:Here

    题意

    给定一个长度为 (n) 的序列 (a_1) ~ (a_n) ,从中选取一段长度在 (s)(t) 之间的连续一段使其平均值最大。((n<=100000))

    分析

    二分答案平均值。

    (a[i]-mid) 中找到一段合法的串使其权值和最大。

    当最大权值和大于等于 (0) 时则 (mid) 上移。

    求最大权值和用单调队列就行。(预处理 (a[i]-mid) 的前缀和 (sum[i])

    Show Code
    
    
    const int N = 1e5 + 10;
    int n, s, t;
    double a[N], sum[N];
    int q[N];
    bool check(double x) {
        for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + (a[i] - x);
        sum[0] = 0;
        int hh = 1, tt = 0;
        memset(q, 0, sizeof(q));
        for (int i = s; i <= n; ++i) {
            while (hh <= tt and sum[q[tt]] > sum[i - s]) tt--;
            q[++tt] = i - s;
            while (hh <= tt and q[hh] < i - t) ++hh;
            if (hh <= tt and sum[i] - sum[q[hh]] >= 0) return true;
        }
        return false;
    }
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        cin >> n >> s >> t;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        double l = -10000, r = 10000;
        while (r - l > 1e-5) {
            double mid = (l + r) / 2.0;
            if (check(mid)) l = mid;
            else r = mid;
        }
        cout << fixed << setprecision(3) << l;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    说实话,mycat就是垃圾,不再更新
    深入理解并发/并行,阻塞/非阻塞,同步/异步
    转载:PHP 协程实现
    转载:异步、并发、协程原理
    第四章总结
    第三节 需要异常
    [第四章] 测试依赖性和异常
    第三章总结
    第三节 MVC应用程序架构和测试
    第二节 PHPUnit测试的剖析
  • 原文地址:https://www.cnblogs.com/RioTian/p/15063532.html
Copyright © 2011-2022 走看看