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

题目大意:找长度不超过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;

}

你可能感兴趣的:(sequence)