HDU 3415 Max Sum of Max-K-sub-sequence

时间:2024-01-18 18:34:08

题目大意:找长度不超过k的最大字段和。

题解:单调队列维护之前k的最小值,思想是对于每一个入队的新元素,如果队尾元素比其大则一直删减,然后插入新元素,对于队首的元素若与当前枚举两相差超过k则直接删去。

#include <cstdio>
using namespace std;
int a[100005],s[200010],num[200010];
int T,n,m,st,ed,h,t,maxs;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
int i,j,k; s[0]=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
for(int i=n+1;i<=2*n;i++)s[i]=s[i-1]+a[i-n];
h=1; t=0; maxs=~0U>>1; maxs=-maxs;
for(int i=1;i<=n+m;i++){
while(h<=t&&s[num[t]]>s[i-1])t--;
num[++t]=i-1;
while(h<=t&&i-num[h]>m)h++;
if(s[i]-s[num[h]]>maxs){
maxs=s[i]-s[num[h]];
st=num[h]+1; ed=i;
}
}
if(st>n)st=st-n; if(ed>n)ed=ed-n;
printf("%d %d %d\n",maxs,st,ed);
}
return 0;
}