loj10175. 「一本通 5.5 例 1」滑动窗口

思路;
  单调队列经典题。

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 1000010;
void qread(int &x){
    x = 0;
    register int ch = getchar(), flag = 0;
    while(ch < '0' || ch > '9'){
        if(ch == '-')
            flag = 1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
        x = 10 * x + ch - 48, ch = getchar();        
    if(flag)    x = -x;
}
int qu[maxn], pos[maxn];
int dpmax[maxn], dpmin[maxn];
int head, tail;
int data[maxn];
int n, k;
void DPmax(){
    head = 1, tail = 0;
    for(int i = 1; i <= n; ++i)
    {
        while(pos[head] < i - k + 1 && head <= tail)    head++;    
        while(data[i] >= qu[tail] && head <= tail)        tail--;
        pos[++tail] = i;
        qu[tail] = data[i];
        dpmax[i] = qu[head];
    }
}

void DPmin(){
    head = 1, tail = 0;
    for(int i = 1; i <= n; ++i)
    {
        while(pos[head] < i - k + 1 && head <= tail)    head++;
        while(data[i] <= qu[tail] && head <= tail)        tail--;
        pos[++tail] = i;
        qu[tail] = data[i];
        dpmin[i] = qu[head];
    }
}
int main(void){
    qread(n);
    qread(k);
    for(int i = 1; i <= n; ++i)
        qread(data[i]);
    DPmin();
    DPmax();
    for(int i = k; i <= n; ++i)
        printf("%d ", dpmin[i]);
    putchar('\n');
    for(int i = k; i <= n; ++i)
        printf("%d ", dpmax[i]);
    putchar('\n');        
}

猜你喜欢

转载自www.cnblogs.com/junk-yao-blog/p/9503850.html