标签:
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2622 Accepted Submission(s): 860
求前缀和,加倍序列。
要满足前k个和都>=0,只需最小值>=0,所以用单调队列维护一个最小的前缀和sum[i],(i>=j-n+1),这样就保证了sum[j]-sum[i]最大,所以区间【j-n+1,i]最小。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int MAXN = 1e6 + 100; int num[MAXN]; int sum[MAXN]; int q[MAXN]; int main(){ int n; while(~scanf("%d", &n), n){ sum[0] = 0; for(int i = 1; i <= n; i++){ scanf("%d", num + i); sum[i] = sum[i - 1] + num[i]; } for(int i = n + 1; i <= 2*n; i++) sum[i] = sum[i - 1] + num[i - n]; // for(int i = 0; i <= 2*n; i++) // printf("%d ", sum[i]);puts(""); int head = 0, tail = -1, ans = 0; for(int i = 1; i <= 2 * n; i++){ while(head <= tail && sum[i] < sum[q[tail]])tail--; q[++tail] = i; // printf("i = %d %d %d\n", i, sum[q[head]], sum[i - n]); if(i > n && sum[q[head]] - sum[i - n] >= 0)ans++; while(head <= tail && q[head] <= i - n)head++; } printf("%d\n", ans); } return 0; }
Non-negative Partial Sums(单调队列)
标签:
原文地址:http://www.cnblogs.com/handsomecui/p/5532419.html