单调队列+IO优化 POJ——Sliding Window

来源:互联网 发布:淘宝网变形金刚 编辑:程序博客网 时间:2024/05/16 01:40
////Sliding Window,当数据范围达到1000000时,划分树就已经吃不消了,由于求的是最大和最小,因此用单调队列来维护
这种写法750ms过的,若全部换成scanf和printf就会超时,只换掉scanf 2400ms,可以看出优省出的时间!
#include <iostream>
#include<cstdio>
#include<algorithm>
#include <cstring>
#include <limits.h>
using namespace std;
const int MAX = 1000011;
int a[MAX];
int q[MAX];
int n, m;
//有符号

inline void in(int &d) {
    char ch;
    int a;
    while (ch = getchar(), (ch < 48 || ch > 57) && ch != 45);
    ch == 45 ? (d = 0, a = -1) : (d = ch - 48, a = 1);
    while (ch = getchar(), ch < 58 && ch > 47) d = d * 10 + ch - 48;
    d *= a;
}

/*
//无符号
inline void in(int &d) {
    char ch;
    while (ch = getchar(), ch < 48 || ch > 57);
    d = ch - 48;
    while (ch = getchar(), ch < 58 && ch > 47) d = d * 10 + ch - 48;
}
 */

void putint(int n) {
    static char buf[32];
    register int pos;
    register int x = n;
    if (x == 0) {
        putchar('0');
        return;
    }
    if (x == INT_MIN) { // x = -x do not work for the minimal value of int, so process it first
        printf("%d", x);
    }
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    pos = 0;
    while (x > 0) {
        buf[pos] = x % 10 + '0';
        x /= 10;
        pos++;
    }
    pos--;
    while (pos >= 0) {
        putchar(buf[pos]);
        pos--;
    }
}

int start, end;

void get_MAX(int i) {
    if (start == -1) {
        end = start = 0;
        q[start] = i;
        return;
    }

    /*自我发明这种写法,简明扼要!!!*/
    while (start <= end && i - q[start] >= m) start++;
    while (start <= end && a[i] > a[q[end]]) end--;
    end++;
    q[end] = i;
}

void get_MIN(int i) {
    if (start == -1) {
        end = start = 0;
        q[start] = i;
        return;
    }

    while (start <= end && i - q[start] >= m) start++;
    while (start <= end && a[i] < a[q[end]]) end--;
    end++;
    q[end] = i;
}

int main() {
    while (scanf("%d%d", &n, &m) == 2) {

        for (int i = 0; i < n; i++) {
            in(a[i]);
        }

        start = end = -1;
        for (int i = 0; i < m - 1; i++) {
            get_MIN(i);
        }
        for (int i = m - 1; i < n; i++) {
            get_MIN(i);
            putint(a[q[start]]);
            if (i < n - 1) {
                putchar(' ');
            } else {
                putchar('\n');
            }
        }

        start = end = -1;
        for (int i = 0; i < m - 1; i++) {
            get_MAX(i);
        }
        for (int i = m - 1; i < n; i++) {
            get_MAX(i);
            putint(a[q[start]]);
            if (i < n - 1) {
                putchar(' ');
            } else {
                putchar('\n');
            }
        }
    }
    return 0;
}
原创粉丝点击