罗老师给大家n个数字:a1,a2,a3, .. , an。
这些数字可以循环,ai, ai+1, ai+2, … , an, a1, a2, … , ai-1。
显然,这样的循环有n种。
现在问大家,n种中有多少种保证从第一项到任意项的和大于等于0
比如
3
-1 1 1
有三种:
-1 1 1
1 1 -1
1 -1 1
其中第一种第一项到第1,2,3项的和分别为: -1, 0, 1
第二种第一项到第1,2,3项的和分别为: 1, 2, 1
第三种第一项到第1,2,3项的和分别为: 1, 0, 1
所以第二种和第三种符合,答案为2
输入
输入n
然后输入n个数字ai
输出
输出有多少种符合
样例输入
3
-1 1 1
样例输出
2
提示
【数据规模和约定】
1<=n<=1000000
这些数字可以循环,ai, ai+1, ai+2, … , an, a1, a2, … , ai-1。
显然,这样的循环有n种。
现在问大家,n种中有多少种保证从第一项到任意项的和大于等于0
比如
3
-1 1 1
有三种:
-1 1 1
1 1 -1
1 -1 1
其中第一种第一项到第1,2,3项的和分别为: -1, 0, 1
第二种第一项到第1,2,3项的和分别为: 1, 2, 1
第三种第一项到第1,2,3项的和分别为: 1, 0, 1
所以第二种和第三种符合,答案为2
输入
输入n
然后输入n个数字ai
输出
输出有多少种符合
样例输入
3
-1 1 1
样例输出
2
提示
【数据规模和约定】
1<=n<=1000000
-1000<=ai<=1000
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,i,t,w,ans;
int a[2000001],sum[2000001],g[2000001],id[2000001];
int main()
{
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i];
a[i+n]=a[i];
}
ans=0;
sum[0]=0;
for(i=1;i<=2*n;i++) sum[i]=sum[i-1]+a[i];
t=1;w=1;
g[1]=sum[1];
id[1]=1;
for(i=2;i<=n;i++)
{
while(sum[i]<g[w])
{
w--;
if(w<t) break;
}
w++;
g[w]=sum[i];
id[w]=i;
}
if(g[t]>=0) ans++;
for(i=n+1;i<=2*n-1;i++)
{
while(id[t]<i-n+1)
{
t++;
if(t>w) break;
}
if(w>=t)
while(sum[i]<g[w])
{
w--;
if(w<t) break;
}
w++;
g[w]=sum[i];
id[w]=i;
if(g[t]-sum[i-n]>=0) ans++;
}
cout<<ans<<endl;
return 0;
}