「一本通 5.5 例 2」最大连续和 1 Sec

UPDATE 2023-08-15:修改代码
UPDATE 2023-08-09 : 修复LaTeX公示
Description

给你一个长度为 n 的整数序列\left \{ A_{1},A_{2},...,A_{n} \right \},要求从中找出一段连续的长度不超过 m 的非空子序列,使得这个序列的和最大。

Input

第一行为两个整数 n,m;
第二行为 n 个用空格分开的整数序列,每个数的绝对值都小于 1000。

Output

仅一个整数,表示连续长度不超过 m 的最大非空子序列和。

Sample Input

6 4

1 -3 5 1 -2 3

Sample Output

7

HINT

对于 50% 的数据,1 \leq n,m\leq 10^{^{4}}
对于 100% 的数据,1 \leq n,m\leq 2*10^{^{5}}

代码
#include<bits/stdc++.h>
using namespace std;
const int N = 200010;
long long s[N], a[N], q[N];
int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		s[i] = s[i - 1] + a[i];
	}
	long long maxn = -1e9;
	int head = 0, tail = 0;
	for (int i = 1; i <= n; i++)
	{
		while (head <= tail && q[head] + m < i)head++;	//如果区间大于m,将队头出队。
		maxn = max(maxn, s[i] - s[q[head]]);	//判断区间最大和
		while (head <= tail && s[q[tail]] >= s[i])tail--;	//如队尾元素大于插入元素,为保持队列单调递增,队尾出列
		q[++tail] = i;	//记录插入元素的下标
	}
	cout << maxn;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值