……

解题报告: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\)也行。

posted @ 2020-02-21 19:25  童话镇里的星河  阅读(201)  评论(0编辑  收藏  举报