fzu Problem 1914 Funny Positive Sequence

Problem 1914 Funny Positive Sequence

Accept: 290    Submit: 1240
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

There are n integers a 1,a 2,…,a n-1,a n in the sequence A, the sum of these n integers is larger than zero. There are n integers b 1,b 2,…,b n-1,b n in the sequence B, B is the generating sequence of A and bi = a 1+a 2,+…+a i (1≤i≤n). If the elements of B are all positive, A is called as a positive sequence.

We left shift the sequence A 0,1,2,…,n-1 times, and get n sequences, that is showed as follows:

A(0): a1,a2,…,an-1,an

A(1): a2,a3,…,an,a1

A(n-2): an-1,an,…,an-3,an-2

A(n-1): an,a1,…,an-2,an-1

Your task is to find out the number of positive sequences in the set { A(0), A(1), …, A(n-2), A(n-1) }.

 Input

The first line of the input contains an integer T (T <= 20), indicating the number of cases. Each case begins with a line containing one integer n (1 <= n <= 500,000), the number of elements in the sequence. The next line contains n integers ai(-2,000,000,000≤ai≤2,000,000,000,1≤i≤n), the value of elements in the sequence.

 Output

For each test case, print a line containing the test case number (beginning with 1) and the number of positive sequences.

 Sample Input

231 1 -181 1 1 -1 1 1 1 -1

 Sample Output

Case 1: 1Case 2: 4

 Source

2010年全国大学生程序设计邀请赛(福州)

题意: 给定一个序列,每个点可以做起点形成新序列,每个序列可以形成以头为起点所有长度的新序列Bi,如果所有Bi都大于0,那么这个序列是可以的,求一共几个这样的序列。

思路:逆向思维,从后往前推,如果当前位置《=0,那么则这个位置为起点是不行的,往前推,加到一个直到》0的sum,中间都是不符合的。 要注意一个点,就是如果加到起点,sum还是《=0的,那么要在从最后枚举一遍,因为序列是循环的。

代码:

#include <stdio.h>
#include <string.h>
const int N = 500005;

int t, n, ans, vis[N];
long long num[N], sum;

int main() {
    int cas = 0;
    scanf("%d", &t);
    while (t --) {
	memset(vis, 0, sizeof(vis));
	scanf("%d", &n);
	ans = n; sum = 0;
	for (int i = 1; i <= n; i ++)
	    scanf("%lld", &num[i]);
	sum = num[n];
	if (sum <= 0) {
	    ans --;
	    vis[n] = 1;
	}
	for (int i = n - 1; i >= 1; i --) {
	    if (sum <= 0) {
		sum += num[i];
		if (sum <= 0) {
		    ans --;
		    vis[i] = 1;
		}
	    }
	    else {
		if (num[i] <= 0) {
		    sum = num[i];
		    ans --;
		    vis[i] = 1;
		}
	    }
	}
	if (sum <= 0) {
	    for (int i = n; i >= 1; i --) {
		sum += num[i];
		if (sum <= 0 && !vis[i]) {
		    ans --;
		    vis[i] = 1;
		}
		else if(sum > 0)
		    break;
	    }
	}
	printf("Case %d: %d\n", ++cas, ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值