洛谷p1886滑动窗口最大最小值 双单调队列

#include <iostream>
#include <cstdio>

using namespace std;
int n,k,a[1000007],q1[2000007],q2[2000007],ans1[1000007],ans2[1000007];
int main(){
    while(~scanf("%d%d",&n,&k)){
        int i;
        for(i=1;i<=n;++i) scanf("%d",a+i);
        int l1=1,r1=1,head1=0,tail1=0;
        int l2=1,r2=1,head2=0,tail2=0;
        int c1=0,c2=0;
        while(r1<=n){
            while(r1-l1+1<=k){
                while(head1!=tail1&&a[q1[tail1-1]]<=a[r1]) tail1--;
                q1[tail1++]=r1;r1++;
            }
            while(r2-l2+1<=k){
                while(head2!=tail2&&a[q2[tail2-1]]>=a[r2]) tail2--;
                q2[tail2++]=r2;r2++;
            }
            ans1[c1++]=a[q2[head2]];
            ans2[c2++]=a[q1[head1]];
            l1++;l2++;
            while(head1!=tail1&&q1[head1]<l1) head1++;
            while(head2!=tail2&&q2[head2]<l2) head2++;
        }    
        for(i=0;i<c1;++i) {
            if(i==c1-1) printf("%d\n",ans1[i]);
            else         printf("%d ",ans1[i]);
        }
        for(i=0;i<c2;++i){
            if(i==c2-1) printf("%d\n",ans2[i]);
            else         printf("%d ",ans2[i]);
        }
    }
    return 0;
}

 

posted @ 2017-03-18 16:14  狡啮之仰  阅读(252)  评论(0编辑  收藏  举报