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 sum of the fi rst 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 fi rst 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

通过这个题才对单调队列有一点了解

题意:一个数列,每一次把第一个数放到尾部,判断这个数列对于任意的  i (1<=i<=n) 是否都满足 sum[i]>=0,如果满足ans++,求最大的ans

思路:先把串加倍,队列需要维护长度为n的序列中的最小值放在队首

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
typedef __int64 ll;

#define fre(i,a,b)  for(i = a; i < b; i++)
#define free(i,a,b) for(i = a; i > =b;i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define ssf(n)      scanf("%s", n)
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 2000005

int sum[N],a[N],n;
int que[N],tail,head;

void inque(int i)
{
    while(head<tail&&sum[i]<sum[que[tail-1]])
			tail--;
	que[tail++]=i;
}

void outque(int i)
{
     if(i-n>=que[head])
		head++;
}

int main()
{
	int i,j;
	while(~sf(n),n)
	{
		fre(i,1,n+1)
		 {
		 	sf(a[i]);
		    sum[i]=sum[i-1]+a[i];
		 }
        fre(i,n+1,n*2+1)
         sum[i]=sum[i-1]+a[i-n];

         tail=head=0;
         int ans=0;
         fre(i,1,n)
           inque(i);

		 fre(i,n,n*2)
		 {
		 	inque(i);
		 	outque(i);
		 	if(sum[que[head]]>=sum[i-n]) ans++;
		 }
       pf("%d\n",ans);
	}
   return 0;
}
时间: 2024-10-04 21:56:56

HDU 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 4193 Non-negative Partial Sums-单调队列-(区间最值)

题意:一个数列,求分别以每个元素为首位时(循环),前缀和都非负的序列个数 分析: 首先是个循环序列问题,所以要做处理:把序列复制一遍变成2*n的序列,这样任意一个长度为n的区间就是一种序列,共n种 然后求前缀和就可以用sum[j]-sum[i-1],这个式子表示以第i的元素为首位的序列,然后以第j个元素结尾的前缀和.同一个序列的不同结尾的前缀和每次都是减sum[i-1],只有sum[j]不同,所以我们就求出sum[j]中最小的再减去sum[i-1]看是否小于0即可.sum[]很好求,O(2*n)

HDU 6047 Maximum Sequence (贪心+单调队列)

题意:给定一个序列,让你构造出一个序列,满足条件,且最大.条件是 选取一个ai <= max{a[b[j], j]-j} 析:贪心,贪心策略就是先尽量产生大的,所以就是对于B序列尽量从头开始,由于数据比较大,采用桶排序,然后维护一个单调队列,使得最头上最大. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #i

hdu 2191 (多重背包的单调队列优化)

多重背包单调队列优化是思想是.普通的dp为 dp[i][j]=max{dp[i-1][j-k*v[i]]+k*w[i]}; 其实你可以发现对能更新j是j和一个剩余类.也就是 0, v[i],2v[i],3v[i] ,4v[i]... 1 ,1+v[i],1+2v[i],1+3v[i] ........... v[i]-1,2*v[i]-1...... 更新值存在一个剩余类中,组与组之间不存在更新.那么实际上我们可以写dp写好这样 dp[b+x*v[i]]=max{ dp[b+k*v[i]]+(x

HDU 5380 Travel with candy 单调队列

链接 题解链接:http://www.cygmasot.com/index.php/2015/08/16/hdu_5380 题意: n C 一条数轴上有n+1个加油站,起点在0,终点在n.车的油箱容量为C 下面n个数字表示每个加油站距离起点的距离. 下面n+1行表示每个加油站买进和卖出一单位油的价格.油可以买也可以卖. 问开到终点的最小花费. 思路: 把油箱保持装满,然后维护一个价格单调递增的队列. #pragma comment(linker, "/STACK:1024000000,10240

hdu 5945 Fxx and game 单调队列优化dp

Fxx and game Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Problem Description Young theoretical computer scientist Fxx designed a game for his students. In each game, you will get three integers X,k,t.In each s

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 shi

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