「题解」洛谷 P3512 [POI2010]PIL-Pilots

题目

P3512 [POI2010]PIL-Pilots

简化题意

问你一段序列中最长的最大值与最小值的差不超过一定值的子序列的长度

思路

单调队列。

分别维护最大值和最小值以及下标。

当最大值与最小值的差不在限制内就弹出队首。

在限制内就就更新答案(需要用到上次弹出的数的下标)。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 3000001

int max(int a, int b) { return a > b ? a : b; }

int n, k, ans, last;
struct Node {
    int w, id;
};
struct deque {
    Node a[MAXN];
    int head, tail;
    Node front() { return a[head]; }
    Node back() { return a[tail]; }
    void add(int x, int id) { a[++tail].w = x, a[tail].id = id; }
    void del_back() { --tail; }
    void del_front() { ++head; }
    bool empty() { return tail < head; }
}q1, q2;

int main() {
    scanf("%d %d", &k, &n);
    q1.tail = q2.tail = 0, q1.head = q2.head = 1;
    for (int i = 1, x; i <= n; ++i) {
        scanf("%d", &x);
        while (!q1.empty() && x >= q1.back().w) {
            q1.del_back();
        }
        q1.add(x, i);
        while (!q2.empty() && x <= q2.back().w) {
            q2.del_back();
        }
        q2.add(x, i);
        Node a = q1.front(), b = q2.front();
        while (a.w - b.w > k) {
            if (a.id < b.id) {
                q1.del_front();
                last = a.id;
            }
            else {
                q2.del_front();
                last = b.id;
            }
            a = q1.front();
            b = q2.front();
        }
        ans = max(i - last, ans);
    }
    printf("%d
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13590584.html