解题报告:luogu P5745 【深基附B例】数列求和

题目链接:P5745 【深基附B例】数列求和
现在想说:\(O(N)\)的题要不怎么也想不出来,要不灵光乍现,就像这道题。
我们维护一个类似单调队列的加法单调队列:
若相加大于此数,就将队尾元素弹出,直至满足条件,顺便更新下\(maxn\)值即可。
然后遇见了烦人的头尾双指针,多了个等号就只有\(30\;pts\)了。

\(Code\):

#include<iostream>
#include<cstdio>
using namespace std;
long long sum=0,l=1,r=0,a[4000005],maxn=-1,k,n,sl,sr;
void work()
{
    for(int i=1;i<=n;i++)
    {
        sum+=a[i];
        while(sum>k&&l<i) sum-=a[l++];
        if(sum<=k&&sum>maxn) maxn=sum,sl=l,sr=i;
    }
    return;
}
int main()
{
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    work();
    printf("%lld %lld %lld\n",sl,sr,maxn);
    return 0;
}

代码很短,但思维有一定难度,重要的是我不会证明正确性。
似乎不用\(long\;long\)也行。

猜你喜欢

转载自www.cnblogs.com/tlx-blog/p/12342662.html