#include "towers.h"
#include <map>
#include <queue>
#include <vector>
struct Fenwick {
    std::vector<int> vals;
    void init(int n) {
        vals.resize(n + 1);
    }
    void update(int i, int x) {
        while (i < vals.size()) {
            vals[i] = std::max(vals[i], x);
            i += i & (-i);
        }
    }
    int premax(int r) {
        int ans = 0;
        while (r) {
            ans = std::max(ans, vals[r]);
            r -= r & (-r);
        }
        return ans;
    }
};
int n;
std::vector<int> heights;
std::vector<int> heightsc;
std::vector<std::vector<int>> stc;
std::map<int, int> cc;
std::vector<int> invcc;
void init(int N, std::vector<int> H) {
    invcc.clear();
    cc.clear();
    stc.clear();
    n = N;
    for (int i : H) cc[i] = 0;
    int cccounter = 0;
    for (auto& [x, y] : cc) y = cccounter++, invcc.push_back(x);
    heightsc = heights = H;
    for (int& i : heightsc) i = cc[i];
    stc.push_back(heightsc);
    for (int sz = 1; sz < 20; ++sz) {
        stc.emplace_back();
        for (int i = 0; i + (1 << sz) <= N; ++i) {
            stc[sz].push_back(std::max(stc[sz - 1][i], stc[sz - 1][i + (1 << (sz - 1))]));
        }
    }
}
int rangemax(int l, int r) {
    int sz = r - l + 1;
    int log = -1;
    while (sz) sz >>= 1, ++log;
    return invcc[std::max(stc[log][l], stc[log][r - (1 << log) + 1])];
}
bool can_communicate(int x, int y, int interference) {
    return rangemax(x, y) >= std::max(heights[x], heights[y]) + interference;
}
struct WaitlistCmp {
    bool operator()(int i, int j) {
        return heights[i] > heights[j];
    }
};
int max_towers(int l, int r, int d) {
    std::priority_queue<int, std::vector<int>, WaitlistCmp> waitlist;
    Fenwick tree;
    tree.init(n + 10);
    std::vector<int> ans(n + 10);
    int max = 0;
    for (int i = l; i <= r; ++i) {
        int lo = 0, hi = i;
        while (lo < hi) {
            int mid = (lo + hi + 1) / 2;
            if (rangemax(mid, i) >= heights[i] + d) {
                lo = mid;
            } else {
                hi = mid - 1;
            }
        }
        ans[i] = tree.premax(lo) + 1;
        max = std::max(max, ans[i]);
        waitlist.push(i);
        while (!waitlist.empty() && heights[waitlist.top()] + d <= heights[i]) {
            int j = waitlist.top();
            waitlist.pop();
            tree.update(j + 1, ans[j]);
        }
    }
    return max;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |