Index × A

Index × A(前缀和,带权的那种)

题目大意:给你个序列,给你片段的长度M,求在序列中找出1* Ai+2* Ai+1+ ....+ M* Ai+M-1的最大值;
利用俩个前缀和,普通的前缀和sum[i]=sum[i-1]+num[i],和sumv[i]=sum[i-1]+i*num[i];那么就可以通过
一段带权为(1+k) *A1+k +(2+k) *A2+k+... +(M+k) *AM+k 来减去k * (A1+k +A2+k +...+AM+k)来得到所要的值。然后枚举得到最大值。

AC代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=200010;
const ll INF=0x3f3f3f3f3f3f3f3f;
ll sum[maxn];
ll sumv[maxn];
int main(void)
{
	int N,M;scanf("%d %d",&N,&M);
	for(int i=1;i<=N;i++)
	{
		int x;
		scanf("%d",&x);
		sum[i]=sum[i-1]+x;
		sumv[i]=sumv[i-1]+1ll*x*i;//这里要注意一下,这两个相乘会超出int的范围,所以要转化一下
	}
	ll Max=-INF;
	for(int i=M;i<=N;i++)
		Max=max(Max,(sumv[i]-sumv[i-M])-(i-M)*(sum[i]-sum[i-M]));
	cout<<Max<<endl;
	return 0;
}
posted @ 2022-09-04 13:07  WUTONGHUA02  阅读(16)  评论(0编辑  收藏  举报