1 条题解

  • 0
    @ 2025-8-24 21:28:15

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar fanfansann
    Think twice,code once

    搬运于2025-08-24 21:28:14,当前版本为作者最后更新于2019-12-20 19:30:55,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    我发现题解中大多数用单调队列做的都是错的!!(不仅是用单调队列,题解中其他的方法基本都能被hack)

    不信你试试5 2 5 4 3 2 1,题解中大多数输出的都是7或者1 1 5,输出的都是0 主要是这道题数据太水了

    所以我决定来给出一个用STL做的正确解法,不能误导别人呀

    所以管理员你就让我过了吧

    其他题解之所以会被hack是因为他们光顾着维护队列单调递增(前缀和递增才会保证最大),忘了万一数据是单调递减怎么办。所以我们应该在维护递增之前就判断现在的答案是否为最优。为了达到这个目的我们应该先给队列赋初值0,因为sum[i]-sum[q.front()]这一句,不赋初值就出bug了,正好赋初值之后就可以避免第一个值是最大的,其余都是负的(如5 2 1 -10 -10 -10 -10 -10)这种丧心病狂的数据了。

    
    #include<bits/stdc++.h>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<stdio.h>
    #include<cmath>
    #include<deque>
    #define debug cout<<"ok"<<endl
    typedef long long ll;
    const int maxn=1e7+10;
    const int mod=1e9+7;
    using namespace std;
    int ans=-233333333,n,m,a,sum[maxn];
    deque<int>q;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            sum[i]=sum[i-1]+a;//前缀和
        }
        q.push_back(0);//赋初值
        for(int i=1;i<=n;i++)
        {
            while(q.front()+m<i)
                q.pop_front();//越界就pop
            ans=max(ans,sum[i]-sum[q.front()]);
            while(!q.empty()&&sum[q.back()]>=sum[i])//递减就pop
                q.pop_back();
            q.push_back(i);
        }
        printf("%d\n",ans);
        return 0;
    }
    
    

    快把我顶上去呀,可不能一直这样误导观众呀

    • 1

    信息

    ID
    692
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者