洛谷 [P1440] 求m区间内的最小值 (单调队列)

链接

https://www.luogu.org/problem/P144

题意

  给你一个长度为 n n n的序列 a a a,对于每一个 a [ i ] a[i] a[i],让你求 a [ i ] a[i] a[i]之前的 m m m个数之中的最小值即 [ i − m , i − 1 ] [i-m,i-1] [im,i1],如果 a [ i ] a[i] a[i]之前没有数,输出0,如果数不足 m m m个,则输出 [ 1 , i − 1 ] [1,i-1] [1,i1]中的最小值.

分析

  单调队列维护一个长度 m m m的窗口即可。注意使用读入挂,别用cin,不然会超时。

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define INF 0x7f7f7f7f
#define MAXN 2000005
#define N 200005
#define P 2
//#define MOD 99991
#define MOD(a, b) a >= b ? a % b + b : a

typedef long long ll;

namespace fastIO {
    //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin),
    // p1 == p2) ? EOF : *p1++) char buf[(1 << 22)], *p1 = buf, *p2 = buf;
    inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
            c = getchar();
        }
        while (c >= '0' && c <= '9')
            x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
}  // namespace fastIO

using namespace fastIO;
using namespace std;

int n, m, t1, t2, a[MAXN], q[MAXN];

int main() {
    cin >> n >> m;
    //cin >> a[1];
    //cout << 0 << endl;
    for (int i = 1; i <= n; i++) {
        a[i] = read();
        if (i == 1) {
            printf("0\n");
            q[++t2] = i;
            t1++;
            continue;
        }
        printf("%d\n", a[q[t1]]);
        while (t1 <= t2 && a[i] < a[q[t2]]) {
            t2--;
        }
        q[++t2] = i;
        //cout << q[t2] << " " << q[t1] << endl;
        while (q[t2] - q[t1] + 1 > m) {
            t1++;
        }
    }
}

你可能感兴趣的:(数据结构--单调队列)