hdu3415 单调队列

来源:互联网 发布:java绘图教程 编辑:程序博客网 时间:2024/05/24 05:43

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

单调队列,这题先将数组转换为前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;}


 

原创粉丝点击