HDU - 2993 (讀入優化)

題意

給你n個數和一個數字k,要求所有長度k\geq k的所有連續子序列中,平均值最大的值。

思路

設數組s[i]s[i]代表序列的前綴和,所求的平均值即爲
s[i]s[j]ij(ijk)\frac{s[i]-s[j]}{i-j} (i-j\geq k)
這個值即是直線s[i]=ik+bs[i]=i*k+b的斜率。
需要注意要保證單調隊列的隊首元素即是對於每種情況的最優解。同時維護的是一個下凸殼。

要注意這個題需要快速讀入。需要快速讀入的板子。

代碼
//
// Created by yjq on 2019/9/19.
//

#include <bits/stdc++.h>
//#include <cstdio>
//#include <cstring>
//#include <iostream>
//#include <algorithm>

using namespace std;

#define ll long long
//#define ld long double
//#define ull unsigned long long
//#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)

ll n, k;

inline char nc() {
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline bool _read(ll &sum) {
    char ch = nc();
    if (ch == EOF)
        return 0;
    sum = 0;
    while (!(ch >= '0' && ch <= '9'))ch = nc();
    while (ch >= '0' && ch <= '9')sum = sum * 10 + ch - 48, ch = nc();
    return sum;
}

const int maxn = 1e5 + 10;
ll a[maxn], s[maxn], q[maxn];

//inline int X(int i, int j) {
//    return j - i;
//}

//inline int Y(int i, int j) {
//    return s[j] - s[i];
//}

//inline double DP(int i, int j) {
//    return (double) (s[i] - s[j]) / (double) (i - j);
//}

int main() {
//    __;
    while (_read(n) && _read(k)) {
        for (int i = 1; i <= n; ++i) {
            _read(s[i]);
            s[i] += s[i - 1];
        }
/*    while (cin >> n >> k) {
        for (int i = 1; i <= n; ++i) {
            cin >> s[i];
            s[i] += s[i - 1];
        }*/
        int l = 0, r = 0;
        q[++r] = 0;
        double ans = 0;
        for (int i = 1; i <= n; ++i) {
            int cur = i - k + 1;
            while (l + 1 < r && (s[i] - s[q[l + 1]]) * (i - q[l + 2]) <= (i - q[l + 1]) * (s[i] - s[q[l + 2]]))
                ++l;
            if (i < k)continue;
            ans = max(ans, (double) (s[i] - s[q[l + 1]]) / (double) (i - q[l + 1]));
            while (l + 1 < r &&
                   (s[q[r]] - s[q[r - 1]]) * (cur - q[r]) >=
                   (q[r] - q[r - 1]) * (s[cur] - s[q[r]]))
                --r;
            q[++r] = cur;
        }
        printf("%.2f\n", ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章