2629 好消息,坏消息!

2629 好消息,坏消息!

知道这些信息的好坏度,研究如何不让老板发怒
题意很好理解,给定一个序列,使得这个序列的和不能为负数的方案,很显然,和前缀和单调队列有关系
而且我发现,单调队列和前缀和经常在一起考,并且前缀和这个东西在提高组的有很大的用武之地
对于这个题很显然,一个数列有很多种情况,也很显然,这个题又是一个破环为链的操作
对于破环为链的操作我们已经很熟悉了,需要开两倍的空间
要想让uim同学不被炒鱿鱼,我们只能让这个区间内的和为正数,熟悉前缀和的肯定会明白如何计算区间和,那么这个题其实就没有什么了…吧
我们还需要用单调队列来维护,最后判断区间和是否合法
还有一个小小的bug,我调了好长时间,啊啊啊,我把&&打成了&&&,导致调了一个小时呜呜呜

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int SIZE=2e6+5;
int n;int head=1,tail;int ans;
ll a[SIZE];
ll sum[SIZE]; 
ll q[SIZE];
int main()
{
	cin>>n;
	for(register int i=1;i<=n;i++)//输入n个数 
		cin>>a[i]; 
	for(register int i=1;i<=n-1;i++) 
		a[i+n]=a[i];//破环为链 
	for(register int i=1;i<=2*n-1;i++)
		sum[i]=sum[i-1]+a[i];//计算前缀和 
	for(register int i=1;i<=2*n-1;i++)
	{
		while(head<=tail&&max(i-n+1,1)>q[head]) head++;//判断窗口长度
		while(head<=tail&&sum[i]<=sum[q[tail]]) tail--;//不满足单调性出列 
		q[++tail]=i;
		if(i-n+1>0&&sum[q[head]]-sum[i-n]>=0) ans++;//计算答案 
	}
	cout<<ans<<endl; 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值