luogu 2629 好消息,坏消息

题目描述

uim在公司里面当秘书,现在有n条消息要告知老板。每条消息有一个好坏度,这会影响老板的心情。告知完一条消息后,老板的心情等于之前老板的心情加上这条消息的好坏度。最开始老板的心情是0,一旦老板心情到了0以下就会勃然大怒,炒了uim的鱿鱼。

uim为了不被炒,知道了了这些消息(已经按时间的发生顺序进行了排列)的好坏度,希望研究如何不让老板发怒。

uim必须按照时间的发生顺序逐条将消息告知给老板。不过uim可以使用一种叫“倒叙”的手法,例如有n条消息,小a可以从k,k+1,k+2...n,1,2...k-1这种顺序通报。

他希望知道,有多少个k,从k开始通报到n然后从1通报到k-1可以让老板不发怒。

输入格式

第一行一个整数n(1 <= n <= 10^6),表示有n个消息。

第二行n个整数,按时间顺序给出第i条消息的好坏度Ai(-1000 <= Ai <= 1000)

输出格式

一行一个整数,表示可行的方案个数。

输入输出样例

输入 #1
4
-3 5 1 2 
输出 #1
2

说明/提示

样例解释

[5 1 2 -3]或[1 2 -3 5]

对于25%数据n<=1000

对于75%数据n<=10000

扫描二维码关注公众号,回复: 7185103 查看本文章

对于100%数据n<=10^6

分析

这道题是一样的

我们用前缀和方便求区间和

由于是环形,开两倍

朴素算法,每到一个点时,判断以任意点为起点时的区间和是否小于零,如果小于零,那么不能做为起点

也就是说,每次只保留令sum[i] - sum[j] >= 0的j,到最后剩下的点就是合法起点

也就是满足sum[j-1]<=sum[i]的点保留

嗯?有点眼熟?、

单调队列不就是这个操作嘛

每次入队新值前都会弹出比他大(或小)的值以维护队列单调

OK

代码

 1 /**********************
 2 User:Mandy.H.Y
 3 Language:c++
 4 Problem: luogu 2629
 5 Algorithm:
 6 **********************/
 7 
 8 #include<bits/stdc++.h>
 9 
10 using namespace std;
11 
12 const int maxn = 1e6 + 5;
13 
14 int n,ans;
15 int a[maxn << 1];
16 int sum[maxn << 1];
17 int l,r,q[maxn << 1];
18 
19 template<class T>inline void read(T &x){
20     x = 0;bool flag  = 0;char ch = getchar();
21     while(! isdigit(ch)) flag |= ch == '-',ch = getchar();
22     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
23     if(flag) x = -x;
24 }
25 
26 template<class T>void putch(const T x){
27     if(x > 9) putch(x / 10);
28     putchar(x % 10 | 48);
29 }
30 
31 template<class T>void put(const T x){
32     if(x < 0) putchar('-'),putch(-x);
33     else putch(x);
34 }
35 
36 void file(){
37     freopen("2629.in","r",stdin);
38     freopen("2629.out","w",stdout);
39 }
40 
41 void readdata(){
42     read(n);
43     for(int i = 1;i <= n; ++ i) read(a[i]),a[i+n]=a[i];
44     for(int i = 1;i <= n + n; ++ i) sum[i] = sum[i - 1] + a[i];
45 }
46 
47 void work(){
48     
49     for(int i = 1;i <= n + n; ++ i){
50         while(l < r && q[l] + n <= i ) ans++,l++;
51         q[r++] = i;
52         while(l < r && sum[q[r-1]-1] > sum[i]) r--;
53         
54     }
55     put(ans);
56 }
57 
58 int main(){
59 //    file();
60     readdata();
61     work();
62     return 0;
63 }
View Code

猜你喜欢

转载自www.cnblogs.com/Mandy-H-Y/p/11469411.html