题目链接: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
",sl,sr,maxn);
return 0;
}
代码很短,但思维有一定难度,重要的是我不会证明正确性。
似乎不用(long;long)也行。