hdu 4193 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
方法 一
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;

int sum[2000006];
int sk[2000006];

int main( )
{
    int i,j,top,hid,N,val,res;
    while( scanf("%d",&N) && N )
    {
        for( i = 1; i <= N; i++ )
        {
            scanf("%d",&sum[i]);
            sum[i+N] = sum[i];
        }
        for( i = 2; i <= N*2; i++ )
            sum[i] += sum[i-1];
        top = hid = 1; sk[1] = 1,res = 0;
        for( i = 2; i <= N*2; i++ )
        {
            while( top <= hid && sum[i] < sum[sk[hid]] )  hid--;
            while( top <= hid && i > N && sk[top] + N < i ) top++; 
                                                   sk[++hid] = i;
            if(  i > N && sum[sk[top]] - sum[i-N] >= 0 ) res++;
        }
            printf("%d\n",res);
    }
    //system("pause");
    return 0;
}


方法 二

#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> #include<cmath>
using namespace std; struct point { int w,num; }q[1000006]; int val[1000006]; int Min[1000006]; bool cmp( point a,point b ) { return a.w < b.w; } int min( int a,int b ) { return a>b?b:a; } int main( ) { int N,i,k,ans; while( scanf("%d",&N) && N ) { val[0] = 0; Min[0] = 1000000001; for( i = 1; i <= N; i++ ) { scanf("%d",&val[i]); val[i] += val[i-1]; Min[i] = min( Min[i-1],val[i] ); q[i].w = val[i]; q[i].num = i; } sort( &q[1],&q[1] + N,cmp ); k = 1; ans = 0; for( i = 1; i <= N; i++ ) if( val[i] < 0 ) break; if( i == N + 1 ) ans++; for( i = 1; i < N; i++ ) { int sum = val[N] - val[i]; if( sum < 0 ) continue; int sta = i + 1; while( q[k].num < sta ) k++; if( k >= N + 1 ) break; if( q[k].w - val[i] < 0 ) continue; if( Min[i] + sum >= 0 ) ans++; } printf("%d\n",ans); } //system("pause"); return 0; }

posted on 2013-03-11 23:13  浪舟  阅读(180)  评论(0编辑  收藏  举报

导航