题解:ABC267C - Index × A(Continuous ver.)

题解:ABC267C - Index × A(Continuous ver.)

·题目

C - Index × A(Continuous ver.)

·难度

算法难度:入门

思维难度:入门

调码难度:普及

综合评价:简单

·算法

滚动求值优化

·思路

如果每次遍历开始位置,并向后推移m位求和O(nm)会超时。因此考虑优化。

从原来的式子a[i]*1+a[i+1]*2+a[i+2]*3+...+a[i+m-1]*m(即从a的第i项开始到第i+m+1项结束取出b)变为a[i]*0+a[i+1]*1+a[i+2]*2+...+a[i+m-1]*(m-1)+a[i+m]*m(即从a的第i+1项开始到第i-m项结束取出b),两者之间差了a[i]+a[i+1]+a[i+2]+...+a[i+m-1]-a[i+m]*m,因此在每次遍历起始点i时维护sum表示a[i]+a[i+1]+a[i+2]+...+a[i+m-1]的值,每次更新时减去差值即可。此时时间复杂度是O(n+m),可以AC。

另请参见:题解:ABC267C - Index × A(Continuous ver.)(不要怀疑,就是我录的)。

·代码

AC提交记录

#include<bits/stdc++.h>
#define N 220000
using namespace std;
long long ans=-((1LL)<<60),sum=0,tmp=0;
//ans表示最终答案,sum表示的是当前的i到i+m-1之间所有a的和,tmp表示从a的当前的i到i+m-1项取出的数形成b此时的答案
int a[N]={},m=0,n=0;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    //输入
    for(int i=1;i<=m;i++){
        sum+=a[i];
        tmp+=a[i]*1LL*i;
    }
    //sum和tmp初始值
    for(int i=1;i<=n-m+1;i++){
        ans=max(ans,tmp);
        //用当前答案(tmp)更新ans
        tmp=tmp-sum+a[i+m]*1LL*m;
        //更新tmp,就是往前滚动,已将出现的a数乘数减去一,形象的写成把整体减去一次sum,之后把最后面的数添加进来(其实也就是减去差值)
        sum=sum-a[i]+a[i+m];
        //更新sum,去掉开头,加上新的结尾
    }
    printf("%lld\n",ans);
    //输出答案
    return 0;
}

·注意

开long long(要不然会WA)。

数据范围不要写错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值