poj 2823 Sliding Window(单调队列)

来源:互联网 发布:网络格言 编辑:程序博客网 时间:2024/06/08 02:06

tle了好几发,搜题解,题解说用c++提交就不会tle了,然后A掉
《挑战程序设计竞赛》里面讲双端队列的应用讲的就是这个,只不过那里面只讲了求最小值。
这里写图片描述

#include <stdio.h>#include <string.h>template <class T>inline bool scan_d(T &ret){    char c;    int sgn;    if(c=getchar(),c==EOF) return 0;    while(c!='-'&&(c<'0'||c>'9')) c=getchar();    sgn=(c=='-')?-1:1;    ret=(c=='-')?0:(c-'0');    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');    ret*=sgn;    return 1;}const int MAXN = 1e6+10;int que[MAXN],oque[MAXN];int num[MAXN];int res[MAXN],ores[MAXN];int len,olen;int head,tail,ohead,otail;int n,k;int main(){    scan_d(n);    scan_d(k);    for(int i = 0; i < n; ++i)        scan_d(num[i]);    for(int i = 0; i < n; ++i)    {        while(head < tail && num[que[tail-1]] >= num[i])            tail--;        que[tail++] = i;        if(i-k+1 >= 0)        {            res[len++] = num[que[head]];            if(que[head] == i-k+1)                ++head;        }        while(ohead < otail && num[oque[otail-1]] <= num[i])            otail--;        oque[otail++] = i;        if(i-k+1 >= 0)        {            ores[olen++] = num[oque[ohead]];            if(oque[ohead] == i-k+1)                ohead++;        }    }    for(int i = 0; i < len; ++i)        printf("%d ",res[i]);    printf("\n");    for(int i = 0; i < olen; ++i)        printf("%d ",ores[i]);    printf("\n");    return 0;}