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;
}

本文讨论了如何利用前缀和和单调队列技巧解决一个关于序列和的挑战,确保区间和始终非负,避免UIM同学的职场困境。通过破环为链的操作和空间优化,展示了如何在编程中应用这些概念,特别是在C++代码示例中。
2096

被折叠的 条评论
为什么被折叠?



