44 lines
1.2 KiB
C++
44 lines
1.2 KiB
C++
|
|
#include <bits/stdc++.h>
|
|||
|
|
using namespace std;
|
|||
|
|
typedef long long LL;
|
|||
|
|
const int N = 4e5 + 10;
|
|||
|
|
|
|||
|
|
int n;
|
|||
|
|
LL a[N], s[N]; // 原数组,前缀和数组
|
|||
|
|
int q[N], L, R; // 滑动窗口,左端点,右端点
|
|||
|
|
LL ans; // 答案
|
|||
|
|
int main() {
|
|||
|
|
cin >> n;
|
|||
|
|
for (int i = 1; i <= n; i++) {
|
|||
|
|
cin >> a[i];
|
|||
|
|
a[n + i] = a[i]; // 破环成链
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 1; i <= 2 * n; i++) // 一维前缀和
|
|||
|
|
s[i] = s[i - 1] + a[i];
|
|||
|
|
|
|||
|
|
// 滑动窗口
|
|||
|
|
L = R = 1; // 初始化滑动窗口长度为0
|
|||
|
|
ans = -1e18; // 初始化答案为-1e18
|
|||
|
|
|
|||
|
|
for (int i = 1; i <= 2 * n; i++) {
|
|||
|
|
// 维护滑动窗口,确保窗口长度不超过n
|
|||
|
|
while (L <= R && q[L] < i - n)
|
|||
|
|
L++;
|
|||
|
|
|
|||
|
|
// 计算当前位置i与窗口内最小前缀和的差,即为以i结尾的最大子段和
|
|||
|
|
LL currentSum = s[i] - s[q[L]];
|
|||
|
|
ans = max(ans, currentSum);
|
|||
|
|
|
|||
|
|
// 维护单调队列,保证队列中的前缀和是单调递增的
|
|||
|
|
// 如果新的前缀和更小,则队尾的更大值都不可能是最优解,可以删除
|
|||
|
|
while (L <= R && s[i] < s[q[R]])
|
|||
|
|
R--;
|
|||
|
|
|
|||
|
|
// 将当前位置加入队列
|
|||
|
|
q[++R] = i;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
printf("%lld\n", ans); // 输出答案
|
|||
|
|
return 0;
|
|||
|
|
}
|