一发nlogn的AC提交
查看原帖
一发nlogn的AC提交
537934
litjohn楼主2024/11/8 23:01

一点卡常建议:

  1. 手写deque
  2. 给用的次数很多的函数加inline
  3. 如果你差几十ms卡过,使用fread快读
#include <bits/stdc++.h>
using namespace std;

const int BUFFER_SIZE = 1 << 20;  // 缓冲区大小
char buffer[BUFFER_SIZE], *buf_ptr = buffer + BUFFER_SIZE;

inline char get_char() {
    if (buf_ptr == buffer + BUFFER_SIZE) {
        fread(buffer, 1, BUFFER_SIZE, stdin);
        buf_ptr = buffer;
    }
    return *buf_ptr++;
}

inline int fast_read_int() {
    int x = 0, sign = 1;
    char ch = get_char();
    while (ch < '0' || ch > '9') {  // 跳过非数字字符
        if (ch == '-') sign = -1;
        ch = get_char();
    }
    while (ch >= '0' && ch <= '9') {  // 读取数字
        x = x * 10 + (ch - '0');
        ch = get_char();
    }
    return x * sign;
}

template<typename T, size_t Capacity>
class StaticDeque {
public:
    StaticDeque() : l_(0), r_(0), size_(0) {}

    // 向前端插入
    inline void push_front(const T &value) {
        //        if (is_full()) throw std::overflow_error("Deque is full");
        l_ = (l_ + 1 != Capacity) ? l_ + 1 : 0;// 手动调整 l_
        data_[l_] = value;
        ++size_;
    }

    // 向后端插入
    inline void push_back(const T &value) {
        //        if (is_full()) throw std::overflow_error("Deque is full");
        data_[r_] = value;
        r_ = (r_ + 1 != Capacity) ? r_ + 1 : 0;// 手动调整 r_
        ++size_;
    }

    // 从前端移除
    inline void pop_front() {
        //        if (is_empty()) throw std::underflow_error("Deque is empty");
        l_ = (l_ + 1 != Capacity) ? l_ + 1 : 0;// 手动调整 l_
        --size_;
    }

    // 从后端移除
    inline void pop_back() {
        //        if (is_empty()) throw std::underflow_error("Deque is empty");
        r_ = (r_ != 0) ? r_ - 1 : Capacity - 1;// 手动调整 r_
        --size_;
    }

    // 获取前端元素
    inline T &front() {
        //        if (is_empty()) throw std::underflow_error("Deque is empty");
        return data_[l_];
    }

    // 获取后端元素
    inline T &back() {
        //        if (is_empty()) throw std::underflow_error("Deque is empty");
        return data_[(r_ == 0) ? Capacity - 1 : r_ - 1];
    }

    inline bool is_empty() const { return size_ == 0; }
    inline bool is_full() const { return size_ == Capacity; }
    inline size_t size() const { return size_; }
    inline size_t capacity() const { return Capacity; }
    inline void clear() {
        l_ = r_ = size_ = 0;
    }

private:
    T data_[Capacity];
    size_t l_;   // 指向前端位置
    size_t r_;   // 指向后端的下一个插入位置
    size_t size_;// 当前队列大小
};

int n, k;
array<int, 3000005> a;
StaticDeque<int, 3000005> q1, q2;//min and max

bool check(int x) {
    q1.clear();
    q2.clear();

    for (int i = 1; i < x; ++i) {
        while (!q1.is_empty() && a[q1.back()] >= a[i]) {
            q1.pop_back();
        }
        q1.push_back(i);
        while (!q2.is_empty() && a[q2.back()] <= a[i]) {
            q2.pop_back();
        }
        q2.push_back(i);
    }

    for (int i = x; i <= n; ++i) {
        while (!q1.is_empty() && q1.front() <= i - x) {
            q1.pop_front();
        }
        while (!q1.is_empty() && a[q1.back()] >= a[i]) {
            q1.pop_back();
        }
        q1.push_back(i);
        while (!q2.is_empty() && q2.front() <= i - x) {
            q2.pop_front();
        }
        while (!q2.is_empty() && a[q2.back()] <= a[i]) {
            q2.pop_back();
        }
        q2.push_back(i);

        if (a[q2.front()] - a[q1.front()] <= k) {
            return true;
        }
    }
    return false;
}

int main() {
    k = fast_read_int();  // 使用快读读取 k
    n = fast_read_int();  // 使用快读读取 n
    for (int i = 1; i <= n; ++i) {
        a[i] = fast_read_int();  // 使用快读读取每个 a[i]
    }

    int l = 1, r = n;
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (check(mid)) {
            l = mid;
        } else {
            r = mid - 1;
        }
    }
    printf("%d\n", l);  // 使用 printf 输出结果
    return 0;
}
2024/11/8 23:01
加载中...