维护一个前缀最小值和一个后缀和和一个后缀的前缀最小值
#include<cstdio>
#include<iostream>
//using namespace std;
int n;int z[1999999],q[1999999],s[1999999],h[1999999],top,tot;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&z[i]);
tot+=z[i];
q[i]=std::min(q[i-1],tot);
}
h[n]=z[n],s[n]=z[n];
for(int i=n-1;i>=1;i--)
{
h[i]=std::min(h[i+1]+z[i],z[i]);
s[i]=s[i+1]+z[i];
}
for(int i=1;i<=n;i++)
if(h[i]>=0&&q[i-1]+s[i]>=0)top++;
printf("%d",top);
return 0;
}
维护一个栈,用负数吞噬他,找出所有的正数
#include<cstdio>
int n;int z[1999999],stuck[1999999],top;
int main()
{
int n;
scanf("%d",&n);
for(int j=1;j<=n;j++)
scanf("%d",&z[j]);
for(int j=1;j<=n;j++)
{
stuck[++top]=z[j];
while(stuck[top]<0&&top>1)
{
top--;
stuck[top]+=stuck[top+1];
stuck[top+1]=0;
}
while(stuck[top]<0)
{
stuck[top]+=z[n];
n--;
if(n<j)
{
printf("0");
return 0;
}
}
}
printf("%d",top);
return 0;
}