很好的单调队列优化DP,一开始以为扫一遍记录sum就可以了,贡献了3个Wrong之后发现想漏了情况,看了网上的思想,自己写了个单调队列维护前缀和,各种调试之后终于水过,主要问题是自己没考虑清楚边界情况,然后嵌套数组的时候直接用下标了。
ACcode:
#include<cstdio>
#include<iostream>
const int nsize=111111;
int n,k,T;
int Maxs,Left,Right,Down,Up;
int Sum[nsize<<1],A[nsize],Q[nsize<<1];
void Queue_In(int Index)
{
while (Down<Up&&Sum[Index]<Sum[Q[Up-1]])
Up--;
while (Down<Up&&Q[Down]+k<=Index)
Down++;
Q[Up++]=Index;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out1.txt","w",stdout);
int cas=0;
scanf("%d",&T);
while (T--)
{
cas++;
scanf("%d %d",&n,&k);
for (int i=1;i<=n;i++)
{
scanf("%d",A+i);
Sum[i]=Sum[i-1]+A[i];
}
for (int i=1;i<k;i++)
Sum[n+i]=Sum[n+i-1]+A[i];
Sum[0]=Down=Up=0;
Maxs=A[1];
Left=Right=1;
Queue_In(0);
for (int i=1;i<n+k;i++)
{
if ((Sum[i]-Sum[Q[Down]])>Maxs)
{
Maxs=Sum[i]-Sum[Q[Down]];
Left=Q[Down]+1;
Right=i;
}
Queue_In(i);
}
if (Right>n) Right-=n;
printf("%d %d %d\n",Maxs,Left,Right);
}
return 0;
}