[Luogu] P1440 求m区间内的最小值

题目描述

一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。

题目解析

没啥意思。

单调队列练手题

题解里看到特别好的一句话:

每次新元素进来时:

1.把比新元素“老”,价值还不如新元素的一律出队。

2.无论价值多高,过期的元素一律出队。

 

Code

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

const int MAXN = 2000000 + 5;

struct Node {
    int id;
    int val;
    friend bool operator >= (Node x,Node y) {
        return x.val >= y.val;
    }
} a[MAXN];

int n,m;
int ans[MAXN];

deque<Node> Q;

inline int rd() {
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {f=ch=='-'?-1:1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++) {
        a[i].id = i;
        a[i].val = rd();
    }
    ans[1] = 0;
    for(int i = 2;i <= n;i++) {
        while(!Q.empty() && Q.back() >= a[i-1]) Q.pop_back();
        Q.push_back(a[i-1]);
        while(Q.front().id < i-m) Q.pop_front();
        ans[i] = Q.front().val;
    }
    for(int i = 1;i <= n;i++) printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/floatiy/p/9877796.html