[解题记录] P2629 好消息,坏消息


P2629 好消息,坏消息

解题思路

暴力枚举每个 \(k\) 的复杂度是 \(\mathcal{O(n^2)}\) 的,而且可以看出这个是一个环,为了方便实现,我们要使用断环

为链的方法,这样用关心 \(k\)\((n+k-1)\) 的值就行了,由于我们需要知道一段数的值,所以想到要用

前缀和,但是这并不能保证每一段都大于 \(0\) ,我们应维护每个区间的最小值,然后用最小值减去区间的

开头再判断即可


code

#include 
#define int long long
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return x*f;
}
const int N=2e6+10;
int a[N],n,tot,q[N],l=1,r,s[N];
signed main(){
    n=read();
    for(int i=1;i<=n;++i) a[i+n]=a[i]=read();
    for(int i=1;i<2*n;++i) s[i]=a[i]+s[i-1];
    for(int i=1;i<2*n;++i){
	while(l<=r&&q[l]<=i-n) l++;
	while(l<=r&&s[q[r]]>=s[i]) r--;
	q[++r]=i;
	if(i>=n){
	    if(s[q[l]]-s[i-n]>=0) tot++;
	}
    }
    cout<

相关