4681: 【GESP2503六级】环线

内存限制:64 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:1 解决:1

题目描述

欢坐地铁。地铁环线有$n$ 个车站,依次以$1,2,...,n$ 标号。车站 $i$($1\le i< n$ )的下一个车站是车站$i+1$ 。特殊地,车站$n$ 的下一个车站是车站$1$ 。
小 A 会从某个车站出发,乘坐地铁环线到某个车站结束行程,这意味着小 A 至少会经过一个车站。小 A 不会经过一个车站多次。当小 A 乘坐地铁环线经过车站$i$ 时,小 A 会获得$a_i$ 点快乐值。请你安排小 A 的行程,选择出发车站与结束车站,使得获得的快乐值总和最大。

输入

第一行,一个正整数$n$ ,表示车站的数量。
第二行,$n$ 个整数$a_1,a_2,...,a_n$ ,分别表示经过每个车站时获得的快乐值。

输出

一行,一个整数,表示小 A 能获得的最大快乐值。

样例输入 复制

4
-1 2 3 0

样例输出 复制

5

提示

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 4e5 + 5;
int n;
long long a[N], pre[N];
int q[N], ql, qr;
long long ans;
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
        a[n + i] = a[i];
    }
    for (int i = 1; i <= 2 * n; i++)
        pre[i] = pre[i - 1] + a[i];
    ql = qr = 1;
    ans = -1e18;
    for (int i = 1; i <= 2 * n; i++) {
        while (ql <= qr && q[ql] < i - n)
            ql++;
        ans = max(ans, pre[i] - pre[q[ql]]);
        while (ql <= qr && pre[i] < pre[q[qr]])
            qr--;
        q[++qr] = i;
    }
    printf("%lld\n", ans);
    return 0;
}