hdu3415 单调队列

单调队列,最近状态不好啊。。省赛了,要加油。。

单调队列,这题先将数组转换为前N项和的形式,然后遍历一遍,求a[k-i]即k到i的最大值,其中,控制i的范围。。。

然后单调队列从一开始判断,保持队头为最小值,然后加上判断语句,若i-s【top】>k 队头退队即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[200020],b[200020],s[200020];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        a[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
            a[i]=a[i]+a[i-1];
        }
        for(int i=n+1;i<=n+m;i++)
        {
            a[i]=b[i-n]+a[i-1];
        }
        int ans=-1<<30;
        int r,l;r=1;l=1;
        int top=0;int tail=0;int last=0;

        for(int k=1;k<=n+m;k++)             //(i,k)
        {
            while(top<tail&&a[s[tail-1]]>a[k-1]) tail--;
            s[tail++]=k-1;
            while(top<tail&&k-s[top]>m) top++;

            int tmp=a[k]-a[s[top]];

            if(tmp>ans)
            {
                ans=tmp;
                r=k%n;
                l=(s[top]+1)%n;
            }
        }
        if(r==0)r=n;
        if(l==0)l=n;
        cout<<ans<<' '<<l<<' '<<r<<endl;
    }
    return 0;
}


 

原文地址:https://www.cnblogs.com/amourjun/p/5134147.html