Non-negative Partial Sums(单调队列)

Non-negative Partial Sums

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2622    Accepted Submission(s): 860

Problem Description

You are given a sequence of n numbers a0,..., an-1. A cyclic shift by k positions (0<=k<=n-1) results in the following sequence: ak ak+1,..., an-1, a0, a1,..., ak-1. How many of the n cyclic shifts satisfy the condition that the sum of the first i numbers is greater than or equal to zero for all i with 1<=i<=n?

Input

Each test case consists of two lines. The first contains the number n (1<=n<=106), the number of integers in the sequence. The second contains n integers a0,..., an-1 (-1000<=ai<=1000) representing the sequence of numbers. The input will finish with a line containing 0.

Output

For each test case, print one line with the number of cyclic shifts of the given sequence which satisfy the condition stated above.

Sample Input

3
2 2 1
3
-1 1 1
1
-1
0

Sample Output

3
2
0

题解:给n个数,a0,a1,...an,求ai,ai+1,...an,a1,a2,...ai-1这样的排列种数,使得所有的前k(1<=k<=n)个的和都大于等于0;

求前缀和,加倍序列。

要满足前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;
}
时间: 2024-10-19 19:04:25

Non-negative Partial Sums(单调队列)的相关文章

HDU 4193 Non-negative Partial Sums(想法题,单调队列)

HDU 4193 题意:给n个数字组成的序列(n <= 10^6),求该序列的循环同构序列中,有多少个序列的任意前i项和均大于或等于0. 思路: 这题看到数据规模觉得只能用最多O(nlogn)的算法,然后想到了之前刚做过的有关最小表示法的题,但还没证明出一个做这题有效的算法出来. 后来看过题解,发现用的最多的方法是单调队列,然而我对这个知识点知之甚少orz /*科普君:from单调队列 单调队列是指:队列中元素之间的关系具有单调性,而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作.

HDU 4193 Non-negative Partial Sums(单调队列)

 题目大意: 给定一个长度为n的循环序列,从n个不同位置开始,问有几个位置使得一下情况成立:所有前缀的和都大等于0(n <=1000000). 下午的训练赛,之前没学过单调队列所以用的线段树,一直tle,到了结束也没搞出来.晚上回来看了下,可以用单调队列来做,时间复杂度为O(n). 这道题其实就是看从每个位置开始的最小前缀和是否大于零,但是这是有规律的. 比如从元素1(以下将元素a[i]简写为i)开始的所有前缀和为1,1+2,...,1+2+3+..+n 从2开始的所有前缀和为2, 2+3

HDU Non-negative Partial Sums (单调队列)

Problem Description You are given a sequence of n numbers a0,..., an-1. A cyclic shift by k positions (0<=k<=n-1) results in the following sequence: ak ak+1,..., an-1, a0, a1,..., ak-1. How many of the n cyclic shifts satisfy the condition that the

hdu4193---Non-negative Partial Sums(单调队列 or 单调栈)

Problem Description You are given a sequence of n numbers a0,-, an-1. A cyclic shift by k positions (0<=k<=n-1) results in the following sequence: ak ak+1,-, an-1, a0, a1,-, ak-1. How many of the n cyclic shifts satisfy the condition that the sum of

Parade(单调队列优化dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 902    Accepted Submission(s): 396 Problem Description Panagola, The Lord of city F lik

HDU 5380 Travel with candy (单调队列&amp;贪心)

本文纯属原创,转载请注明出处.http://blog.csdn.net/zip_fan,谢谢. 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5380. Travel with candy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description There are n+1 cities on

HDU 6444 Neko&#39;s loop(单调队列)

Neko has a loop of size nn. The loop has a happy value aiai on the i−th(0≤i≤n−1)i−th(0≤i≤n−1) grid. Neko likes to jump on the loop.She can start at anywhere. If she stands at i−thi−thgrid, she will get aiai happy value, and she can spend one unit ene

【动态规划】【单调队列】tyvj1305 最大子序和

http://blog.csdn.net/oiljt12138/article/details/51174560 单调队列优化dp #include<cstdio> #include<deque> #include<algorithm> #include<iostream> using namespace std; typedef long long ll; int n,m; ll a[300100],ans; deque<int>q; int

hdu_5884_Sort(二分+单调队列)

题目链接:hdu_5884_Sort 题意: 有n个数,每个数有个值,现在你可以选择每次K个数合并,合并的消耗为这K个数的权值和,问在合并为只有1个数的时候,总消耗不超过T的情况下,最小的K是多少 题解: 首先要选满足条件的最小K,肯定会想到二分. 然后是如何来写这个check函数的问题 我们要贪心做到使消耗最小,首先我们将所有的数排序 然后对于每次的check的mid都取最小的mid个数来合并,然后把新产生的数扔进优先队列,直到最后只剩一个数. 不过这样的做法是n*(logn)2 ,常数写的小