维护单调减队列
前缀和为sum
我们要求max(sum[i]-sum[j-1])
变形为sum[i]-min (sum[j-1]) 范围在 i-j+1>k
i从头枚举
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=2e5+1000;
int a[maxn],sum[maxn],q[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
sum[0]=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
int len=n+k-1;
for(int i=n+1;i<=len;i++)
{
sum[i]=sum[i-1]+a[i%n];
}
int head=0,tail=0;
int maxx=-inf;
int le,ri;
for(int i=1;i<=len;i++)
{
while(head<tail&&sum[q[tail-1]]>sum[i-1]) tail--;
q[tail++]=i-1;
while(head<tail&&i-q[head]>k) head++;
if(maxx<sum[i]-sum[q[head]])
{
maxx=sum[i]-sum[q[head]];
le=q[head]+1;
ri=i>n?i%n:i;
}
}
printf("%d %d %d\n",maxx,le,ri);
}
}