poj 2823 简单单调队列优化dp

///给定一个长N的整数序列,用一个大小为K的窗口从头开始覆盖,问第1-第N-K次窗口里面最大的数字和最小的数字。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000012;
int q1[maxn],q2[maxn],a[maxn],n,k,ans1[maxn],ans2[maxn];
int main()
{
    //freopen("//media/学习/ACM/input.txt","r",stdin);
    while(~scanf("%d%d",&n,&k))
    {
        int l=0,r=-1,i,j;
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        for(i=1;i<=n;i++)///得到最大值
        {
            while(l<=r&&a[q1[r]]<a[i])r--;
            q1[++r]=i;
            while(l<r&&q1[l]<i-k+1)l++;
                ans1[i]=a[q1[l]];
               // cout<<l<<" "<<r<<endl;
              ///  cout<<"q1[l]="<<q1[l]<<" "<<i<<" ans1 "<<ans1[i]<<endl;
        }
        for(l=0,r=-1,i=1;i<=n;i++)///得到最小值
        {
            while(l<=r&&a[q2[r]]>a[i])r--;
            q2[++r]=i;
            while(l<r&&q2[l]<i-k+1)l++;
                 ans2[i]=a[q2[l]];
        }
        for(printf("%d",ans2[k]),i=k+1;i<=n;i++)printf(" %d",ans2[i]);printf("\n");
        for(printf("%d",ans1[k]),i=k+1;i<=n;i++)printf(" %d",ans1[i]);printf("\n");
    }
    return 0;
}


你可能感兴趣的:(poj 2823 简单单调队列优化dp)