• Blocks


    Description

    solution

    这题和之前做过的一题的一个套路非常类似:把不是更优的决策给去掉,使得序列变得具有单调性,分析这题:
    发现如果两个右端点 (i),(j) 满足 (sum[j]<sum[i])(j<i),那么 (j) 是不会进入最优决策的.
    同理:如果两个左端点 (i),(j) 满足 (sum[j]<sum[i])(i<j) 那么 (i) 是不会进入最优决策的
    所以我们分别维护一个左右端点的单调栈,然后两个单调指针扫一遍答案取Max即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=1000005;
    inline int gi(){
    	RG int str=0;RG char ch=getchar();
    	while(ch>'9' || ch<'0')ch=getchar();
    	while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    	return str;
    }
    int n,Q,a[N],st[N],q[N],tp=0;ll sum[N];
    
    inline void solve(ll x){
    	int top=0,ans=0,tp=0;
    
    	q[++tp]=0;
    	for(int i=1;i<=n;i++){
    		sum[i]=sum[i-1]+a[i]-x;
    		if(sum[i]<sum[q[tp]])q[++tp]=i;
    	}
    	for(int i=n;i>=1;i--){
    		if(!top || sum[i]>sum[st[top]])st[++top]=i;
    	}
    	
    	for(int i=1;i<=tp;i++){
    		while(top>1 && sum[q[i]]<=sum[st[top-1]])top--;
    		if(q[i]<st[top] && sum[st[top]]-sum[q[i]]>=0)
    			ans=Max(ans,st[top]-q[i]);
    	}
    	printf("%d ",ans);
    }
    
    void work()
    {
    	scanf("%d%d",&n,&Q);
    	for(int i=1;i<=n;i++)a[i]=gi();
    	for(int i=1;i<=Q;i++)solve(gi());
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    【BZOJ4300】绝世好题
    codeforce1051F
    【BZOJ3329】Xorequ
    codeforce739c
    【UVA11825】
    codeforce6E
    CF 1023D Array Restoration
    BZOJ 1911 [APIO2010] 特别行动队
    POJ 3709 K-Anonymous Sequence
    BZOJ 2726 [SDOI2012] 任务安排
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7806714.html
Copyright © 2020-2023  润新知