F - Think Positive
Problem Description
It is well known, that the year on planet Eisiem has n days. Of course, some days are very good for people, while some others are just horrible. Long observations have shown for each day of the year whether this day is good for most people, or bad.
The new president of the Planet Federation wants all people to be happy. He knows that good emotions have a tendency to accumulate, just like bad ones do. The New Year however is a special event and all emotions accumulated by this moment just disappear. Therefore the president wants to change the calendar on Eisiem and choose the new first day of the year, so that the positive emotions would prevail the whole year.
More precisely, for all i from 1 to n let ai be 1 if i-th day is good for most people and -1 if it is bad. Let sjk be the sum of ai for all days from the j-th day of the year to the k-th, that is:
President wants to find such j to order the j-th day to be the first day of the year, that sjk is positive for all k from 1 to n. Since he wants several variants to choose from, he asks you to find all such j. Since he doesn't want to get too much information at once, first of all he wants to know the number of such j. That is exactly your task.
Input
Output
Sample Input
5 1 -1 1 -1 1
Sample Output
1
题意:给一个环,只包含1和-1,求有多少个i,满足从i加到i-1的每一项和都大于0.
思路:将数列*2模拟环,用s数组记录1到si的和,则转化为求有多少个si保证i<j时si<sj。这其中j是大于i的,判断si是否可行其实就是在si+1—si+n中有无比si小或相等的数。也就是判断si是否小于si+1—si+n中的最小值。那就可以用单调队列从后向前维护出每个si+1—si+n中的最小值,逐个判断即可。不过据说此题用1的个数减去-1的个数就是答案,也是醉了。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int N=200005;
struct node
{
int x,v;
}deq[2*N];
int a[N],s[2*N];
int front,back,n;
int main()
{
scanf("%d",&n);
s[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
s[i]=s[i-1]+a[i];
}
for(int i=1;i<=n;i++){
s[i+n]=s[i+n-1]+a[i];
}
front=back=0;
for(int i=2*n;i>n;i--){
while(front<back&&s[i]<deq[back-1].v)back--;
deq[back].v=s[i];
deq[back++].x=i;
}
int ans=0;
for(int i=n;i>=1;i--){
if(deq[front].v>s[i])ans++;
while(front<back&&s[i]<deq[back-1].v)back--;
deq[back].v=s[i];
deq[back++].x=i;
while(deq[front].x>=i+n)front++;
}
printf("%d\n",ans);
return 0;
}