[Solution] ABC341G

Description

Link

长度 \(n\) 的数列 \(A=(A_1,A_2,\ldots,A_n)\)

对于每个 \(k\) \((1\le k\le n)\),选择满足 \(k\le r\le n\) 的整数 \(r\),使得 \(A\) 序列第 \(k\) 项到第 \(r\) 项的平均值的最大。

Solution

\(s_i\)\(a_i\) 的前缀和,\(f_i\)\(i\) 位置的答案。

\[f_{i+1}=\max_{j=i+1}^n \dfrac{s_j-s_i}{j-i} \]

即点 \((i,s_i)\) 和点 \((j,s_j)\) 所在直线斜率的最大值。

倒序枚举,使用单调栈维护上凸壳即可。

Code

#include <cstdio>

#define int long long

using namespace std;

const int N = 200005;

int n, top, a[N], s[N]; double f[N];

double slope(int x, int y) {return 1.0 * (a[x] - a[y]) / (x - y);}

signed main()
{
    scanf("%lld", &n);
    for(int i = 1; i <= n; ++ i)
        scanf("%lld", &a[i]), a[i] += a[i - 1];

    s[++top] = n;
    for(int i = n - 1; i >= 0; -- i)
    {
        while(top > 1 && slope(s[top - 1], i) < slope(s[top - 1], s[top])) -- top;
        f[i + 1] = slope(s[top], i);
        s[++top] = i;
    }
    for(int i = 1; i <= n; ++ i) printf("%.8lf\n", f[i]);

    return 0;
}
posted @ 2024-02-21 11:32  Estelle_N  阅读(27)  评论(0编辑  收藏  举报