环上最大连续和

给定N,K以及一个环:A[1],A[2],A[3],...A[N],其中A[1]的左边是A[N]。
求该环上最大的连续子段和,要求选出的子段长度不超过K。

输入描述:
第一行两个整数N和K。
接下来一行,N个整数表示A[i]。



输出描述:
输出题目要求的最大连续和。






求Max{sum[i]-sum[x]},
单调队列
维护sum[x]。

code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
inline void read(int &a)
{
    int k=1; a=0; char c=getchar();
    while(c<'0'||'9'<c){if(c=='-')k=-1; c=getchar();}
    while('0'<=c&&c<='9'){a=a*10+c-'0'; c=getchar();}
    a*=k;
}
inline void write(int a)
{
    if (a<0){putchar('-');a=-a;}
    if (a>9)write(a/10);
    putchar(a%10+'0');
    return ;
}
int a[200005],q[200005],sum[200005];
int main()
{
    int n,m,i,j;
    cin>>n>>m;
    for (i=1;i<=n;i++)
    {
        read(a[i]);
        a[i+n]=a[i];
    } 
    for (i=1;i<=2*n;i++)
    {
        sum[i]=sum[i-1]+a[i];
    }
    int l=1,r=1,ans=-2147483647;
    q[r]=0;
    for (i=1;i<=n+m;i++)
    {
        while (l<=r&&i-q[l]>m)
        l++;
        if (l<=r&&sum[i]-sum[q[l]]>=ans)
        {
            ans=sum[i]-sum[q[l]];
        }
        while (l<=r&&sum[q[r]]>=sum[i])
        r--;
        q[++r]=i;
    } 
    cout<<ans<<endl;
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/applechina/p/10807133.html