This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "towers.h"
#include <bits/stdc++.h>
#define pb emplace_back
#define fi first
#define se second
#define mp make_pair
#define int long long
using namespace std;
int n;
vector<int> h;
int pv[100005]; // 0: peak, 1: valley, 2: upslope, 3: downslope
int ps[100005];
int mx = 0;
int q = 0;
pair<int, int> seg[400005];
vector<pair<int, int>> ee;
int nn;
void build(int l, int r, int id) {
    if(l == r) seg[id] = mp(h[ee[l].fi], l);
    else {
        int m = (l + r) / 2;
        build(l, m, id * 2);
        build(m + 1, r, id * 2 + 1);
        seg[id] = max(seg[id * 2], seg[id * 2 + 1]);
    }
    return;
}
void upd(int l, int r, int id, int k, int val) {
    if(l == r) seg[id] = mp(val, l);
    else {
        int m = (l + r) / 2;
        if(k <= m) upd(l, m, id * 2, k, val);
        else upd(m + 1, r, id * 2 + 1, k, val);
        seg[id] = max(seg[id * 2], seg[id * 2 + 1]);
    }
    return;
}
pair<int, int> rmq (int l, int r, int id, int ql, int qr) {
    // cerr << l << ' ' << r << ' ' << id << ' ' << ql << ' ' << qr << '\n';
    if(ql > r || qr < l) return mp(-1, -1);
    if(ql <= l && qr >= r) return seg[id];
    int m = (l + r) / 2;
    return max(rmq(l, m, id * 2, ql, qr), rmq(m + 1, r, id * 2 + 1, ql, qr));
}
int lp[200005];
void init(signed N, vector<signed> H) {
    n = N;
    h.pb(2000000000);
    for(auto x: H) h.pb(x);
    h.pb(2000000000);
    ee.pb(mp(0, 0));
    for(int i = 1; i <= n; i++) {
        mx = max(mx, h[i]);
        if(h[i] < h[i - 1] && h[i] < h[i + 1]) pv[i] = 1;
        else if(h[i] > h[i - 1] && h[i] < h[i + 1]) pv[i] = 2;
        else if(h[i] < h[i - 1] && h[i] > h[i + 1]) pv[i] = 3;
        ps[i] = ps[i - 1];
        if(pv[i] == 1) ps[i]++;
        if(pv[i] <= 1) {
            ee.pb(mp(i, pv[i]));
        }
    }
    nn = ee.size() - 1;
    for(int i = 1; i <= 100000; i *= 2) {
        for(int j = i; j < i * 2; j++) lp[j] = i;
    }
    build(1, nn, 1);
    for(int i = 2; i <= nn; i++) {
        assert((pv[ee[i].fi] ^ pv[ee[i - 1].fi]) == 1);
    }
    // for(int i = 1; i <= n; i++) cerr << pv[i] << ' '; cerr << '\n';
    // cerr << nn << '\n';
    return;
}
int solve(int l, int r, int mx, int d) {
    assert(pv[ee[l].fi] == pv[ee[r].fi] && pv[ee[r].fi] == 1);
    // cerr << l << ' ' << r << ' ' << mx << ' ' << d  << '\n';
    if(mx <= 0) return 0;
    if(l > r) return 0;
    // if(l == r && pv[ee[l].se] == 1) return (h[ee[l].se] <= mx);
    assert(l >= 1 && r <= nn);
    auto aa = rmq(1, nn, 1, l, r);
    
    if(pv[ee[aa.se].fi] == 1) {
        assert(l == r);
        // cerr << l << ' ' << r << ' ' << mx << ' ' << d << ' ' << aa.fi << ' ' << aa.se << ' ' << (h[ee[l].fi] <= mx) << '\n';
        return (aa.fi <= mx);
    }
    int a = solve(l, aa.se - 1, min(mx, aa.fi - d), d) + solve(aa.se + 1, r, min(mx, aa.fi - d), d);
    int b = max(solve(l, aa.se - 1, mx, d), solve(aa.se + 1, r, mx, d));
    // cerr << l << ' ' << r << ' ' << mx << ' ' << d << ' ' << aa.fi << ' ' << aa.se << ' ' << max(a, b) << '\n';
    return max(a, b);
}
signed max_towers(signed l, signed r, signed d) {
    l++; r++; q++;
    if(r - l < 2) return 1;
    int el = 0;
    int er = 0;
    for(int i = lp[nn]; i > 0; i /= 2) {
        if(el + i <= nn && ee[el + i].fi < l) el += i;
        if(er + i <= nn && ee[er + i].fi <= r) er += i;
        // cerr << i << ' ' << nn << ' ' << el << ' ' << er << ' ' << ee[el].fi << ' ' << ee[er].fi << ' ' << l << ' ' << r << '\n';
    }
    el++;
    if(el > er) return 1;
    bool lc = false;
    bool rc = false;
    if(pv[l] == 2) {
        lc = true;
        el--;
        pv[l] = 1;
        upd(1, nn, 1, el, h[l]);
    }
    if(pv[r] == 3) {
        rc = true;
        er++;
        pv[r] = 1;
        upd(1, nn, 1, er, h[r]);
    }
    // cerr << el << ' ' << er << '\n';
    if(pv[ee[el].fi] == 0) el++;
    if(pv[ee[er].fi] == 0) er--;
    // cerr << el << ' ' << er << '\n';
    int kk;
    if(el >= er) kk = 1;
    else kk = solve(el, er, 1000000001, d);
    if(lc) {
        pv[l] = 2;
        upd(1, nn, 1, el, h[ee[el].fi]);
    }
    if(rc) {
        pv[r] = 3;
        upd(1, nn, 1, er, h[ee[er].fi]);
    }
    return max(1LL, kk);
}
| # | 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... |