题目描述
PIPI来考察大家序列处理能力啦。
给定一个长度为n的整数序列A,你需要在A中找到一个长度不大于m的连续子序列,要求这个连续子序列的和最大。 注:可以一个数都不选。
例如: 1, -3, 5, 1, -2, 3
当m=4时,maxsum = 5+1-2+3 = 7
当m=2或m=3时,maxsum = 5+1 = 6
输入
第一行是两个正数n, m ( n, m ≤ 300000 )
第二行是n个整数Ai,-1e9<=Ai<=1e9.
输出
输出一个整数表示答案。
样例输入
6 4
1 -3 5 1 -2 3
样例输出
7
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+7;
long long sum[N];
int q[N];
int main()
{
int n,m,v;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&v);
sum[i]=sum[i-1]+v; ///求前缀和
}
int head=0,rear=0; ///单调队列 滑动窗口维护m范围内的最小值
long long ans=0; ///维护m范围内和的最大值
//q[head]=0;
for(int i=1;i<=n;i++)
{
while(head<=rear&&sum[q[rear]]>=sum[i]) rear--; ///单调队列求最小值
q[++rear]=i;
while(head<=rear&&i-q[head]>m) head++;
ans=max(ans,sum[i]-sum[q[head]]); ///sum[i]减最小值 一直维护得到最大的那个值
}
printf("%lld\n",ans);
}