题目:
Description
Input
Output
Sample Input
3 3 1 2 3 8 4 5 -1 -1 1 -1 -1 5 2 -1 -1
Sample Output
6 14 0
循环序列,求出最大的子串和。
思路:
双端队列,。
维护一个不大于n的队列,队尾减队首更新答案。
AC.
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int INF = 1e5;
const int maxn = 1e6+5;
int a[maxn*2], sum[maxn*2];
int deq[maxn*2];
int main()
{
//freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
sum[0] = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
a[i+n] = a[i];
sum[i] = sum[i-1] + a[i];
}
for(int i = n+1; i <= 2*n; ++i) {
sum[i] = sum[i-1] + a[i];
}
int ans = 0;
deq[0] = 0;
int s = 0, t = -1;
for(int i = 1; i <= 2*n; ++i) {
while(s <= t && sum[i] < sum[deq[t]]) {
ans = max(ans, sum[deq[t]] - sum[deq[s]]);
t--;
}
while(s <= t && i - deq[s] > n) {
ans = max(ans, sum[deq[t]] - sum[deq[s]]);
s++;
}
deq[++t] = i;
}
ans = max(ans, sum[deq[t]] - sum[deq[s]]);
printf("%d\n", ans);
}
return 0;
}