Problem p01777 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <cassert>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> PD;
typedef long double ld;

struct Tree {
  typedef int D;
  struct Node;
  typedef Node *NP;
  static Node last_d;
  static NP last;
  struct Node {
    NP l, r;
    int sz;
    D v;
    Node(D v) : l(last), r(last), sz(1), v(v) {}
    Node() : l(nullptr), r(nullptr), sz(0) {}
    void push() {}
    NP update() {
      sz = 1 + l->sz + r->sz;
      return this;
    }
    int lb(D a) {
      if (!sz)
        return 0;
      if (a <= v)
        return l->lb(a);
      return l->sz + 1 + r->lb(a);
    }
    int ub(D a) {
      if (!sz)
        return 0;
      if (v <= a)
        return l->sz + 1 + r->ub(a);
      return l->ub(a);
    }
    D get(int k) {
      if (k == l->sz)
        return v;
      if (k < l->sz) {
        return l->get(k);
      } else {
        return r->get(k - (l->sz + 1));
      }
    }
  } *n;

  static uint xor128() {
    static uint x = 123456789, y = 362436069, z = 521288629, w = 88675123;
    uint t;
    t = (x ^ (x << 11));
    x = y;
    y = z;
    z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
  }
  static NP merge(NP l, NP r) {
    if (!l->sz)
      return r;
    if (!r->sz)
      return l;
    l->push();
    r->push();
    if ((int)(xor128() % (l->sz + r->sz)) < l->sz) {
      l->r = merge(l->r, r);
      return l->update();
    } else {
      r->l = merge(l, r->l);
      return r->update();
    }
  }
  static pair<NP, NP> split(NP x, int k) {
    if (!x->sz)
      return {last, last};
    x->push();
    if (k <= x->l->sz) {
      auto y = split(x->l, k);
      x->l = y.second;
      y.second = x->update();
      return y;
    } else {
      auto y = split(x->r, k - x->l->sz - 1);
      x->r = y.first;
      y.first = x->update();
      return y;
    }
  }

  Tree() : n(last) {}
  Tree(NP n) : n(n) {}
  int sz() { return n->sz; }
  void merge(Tree r) { n = merge(n, r.n); }
  Tree split(int k) {
    auto u = split(n, k);
    n = u.first;
    return Tree(u.second);
  }
  void insert(D v) {
    auto u = split(n, lb(v));
    n = merge(merge(u.first, new Node(v)), u.second);
  }
  void erase(D v) {
    assert(count(v));
    auto u = split(n, lb(v));
    n = merge(u.first, split(u.second, 1).second);
  }
  int count(D v) { return ub(v) - lb(v); }
  int lb(D v) { return n->lb(v); }
  int ub(D v) { return n->ub(v); }
  D get(int k) { return n->get(k); }
};
Tree::Node Tree::last_d = Tree::Node();
Tree::NP Tree::last = &last_d;

/*
?????¶????????§??????????????????
*/

template <int S> struct StarrySkyTree {
  typedef int D;
  static const int N = 1 << S;
  Tree seg[2 * N];
  int sz[2 * N];
  StarrySkyTree() {
    for (int i = 2 * N - 1; i >= N; i--) {
      sz[i] = 1;
    }
    for (int i = N - 1; i >= 1; i--) {
      sz[i] = sz[i * 2] + sz[i * 2 + 1];
    }
  }
  void init() {
    for (int i = 1; i < 2 * N; i++) {
      seg[i] = Tree();
    }
  }

  void update(int k) {
    assert(1 <= k && k < N);
    seg[k] = max(seg[k * 2], seg[k * 2 + 1]);
  }
  void add(int k, D x) {
    k += N;
    seg[k].insert(x);
    while (k > 1) {
      k /= 2;
      seg[k].insert(x);
    }
  }

  D get(int a, int b, D x, int k = 1) {

    if (sz[k] <= a || b <= 0)
      return 0;
    if (a <= 0 && sz[k] <= b)
      return seg[k].lb(x);
    D dl = get(a, b, x, k * 2);
    D dr = get(a - sz[k] / 2, b - sz[k] / 2, x, k * 2 + 1);
    return dl + dr;
  }
};

StarrySkyTree<17> st;
int x[1 << 17];

int main() {
  st.init();
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> x[i];
    st.add(i, x[i]);
  }
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int l, r, e;
    cin >> l >> r >> e;
    l--;
    int mi = min(x[l], x[r - 1]);
    int ma = max(x[l], x[r - 1]);
    mi -= e;
    ma += e + 1;
    int res = st.get(l, r, mi) + ((r - l) - st.get(l, r, ma));
    cout << res << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <cassert>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> PD;
typedef long double ld;

/*
AA Tree?????????????????????multiset
std::multiset?????????????????????insert/erase???RBST????????????????????????
at(k)??§k?????????????´??????¢??????????????????
lb(x)/ub(x)??§lower/upper bound?????????????????????index??§?????£?????????
????????????merge/split?????¨??????????????????????????¨???????????????
?????¨??¨?????????????????????????????????
*/

template <class D, class C = less<D>> struct AAMSet {
  struct Node;
  typedef Node *NP;
  static Node last_d;
  static NP last;
  struct Node {
    NP l, r;
    int level, sz;
    D v;
    Node() : l(nullptr), r(nullptr), level(0), sz(0) {}
    Node(D vv) : l(last), r(last), level(1), sz(1) { v = vv; }
    //?????¢???????????????????????????????????????new????????????????????¨???????????????
    static NP make() { return new Node(); }
    static NP make(D vv) { return new Node(vv); }

    inline void update() { sz = 1 + l->sz + r->sz; }

    inline void push() {}
  } *n;

  static D at(NP n, int k) {
    if (k == n->l->sz)
      return n->v;
    n->push();
    if (k < n->l->sz) {
      return at(n->l, k);
    } else {
      return at(n->r, k - (n->l->sz + 1));
    }
  }
  D at(int k) { return at(n, k); }
  static int lb(NP n, D x) {
    if (n == last)
      return 0;
    if (C()(n->v, x))
      return n->l->sz + 1 + lb(n->r, x);
    return lb(n->l, x);
  }
  int lb(D v) { return lb(n, v); }
  static int ub(NP n, D x) {
    if (n == last)
      return 0;
    if (C()(x, n->v))
      return ub(n->l, x);
    return n->l->sz + 1 + ub(n->r, x);
  }
  int ub(D v) { return ub(n, v); }
  static NP insert(NP n, D x) {
    if (n == last) {
      return Node::make(x);
    }
    n->push();
    if (!C()(n->v, x)) {
      n->l = insert(n->l, x);
      n->update();
    } else {
      n->r = insert(n->r, x);
      n->update();
    }
    n = skew(n);
    n = pull(n);
    return n;
  }
  void insert(D x) { n = insert(n, lb(x), x); }
  static NP erase(NP n, D x) {
    assert(n != last);
    n->push();
    if (!C()(n->v, x) && !C()(x, n->v)) {
      if (n->level == 1) {
        return n->r;
      }
      auto x = at0_with_remove(n->r);
      NP nn = x.first;
      nn->push();
      nn->l = n->l;
      nn->r = x.second;
      nn->level = n->level;
      nn->update();
      return rightdown(nn);
    }
    if (C()(x, n->v)) {
      n->l = erase(n->l, x);
      n->update();
      return leftdown(n);
    } else {
      n->r = erase(n->r, x);
      n->update();
      return rightdown(n);
    }
  }
  void erase(D x) { n = remove(n, lb(x)); }

  static void tp(NP n) {
    if (n == last)
      return;
    n->push();
    tp(n->l);
    cout << n->v << " ";
    tp(n->r);
  }
  void tp() {
    tp(n);
    printf("\\n");
  }
  static void allpush(NP n) {
    if (n == last)
      return;
    n->push();
    allpush(n->l);
    allpush(n->r);
  }
  void allpush() {
    allpush(n);
    return;
  }

  static NP built(int sz, D d[]) {
    if (!sz)
      return last;
    int md = (sz - 1) / 2;
    NP n = Node::make(d[md]);
    n->l = built(md, d);
    n->r = built(sz - (md + 1), d + (md + 1));
    n->level = n->l->level + 1;
    n->update();
    return n;
  }
  AAMSet() : n(last) {}
  AAMSet(NP n) : n(n) {}
  //??¨???????????????n???insert??????????°?????????????????????????????????????????????????
  AAMSet(int sz, D d[]) { n = built(sz, d); }

  //?????¬??????
  int sz() { return n->sz; }
  int size() { return sz(); }
  void merge(AAMSet r) { n = merge(n, r.n); }
  AAMSet split(int k) {
    auto y = split(n, k);
    n = y.first;
    return AAMSet(y.second);
  }
  void insert(int k, D x) { n = insert(n, k, x); }
  void remove(int k) { n = remove(n, k); }

  // AA??¨????????¬????????§??????skew/split
  // split?????????????´???????????????????pull????????´????????????
  static NP skew(NP n) {
    if (n->level == n->l->level) {
      NP L = n->l;
      n->push();
      L->push();
      n->l = L->r;
      L->r = n;
      n->update();
      L->update();
      return L;
    }
    return n;
  }
  static NP pull(NP n) {
    if (n->level == n->r->level && n->r->level == n->r->r->level) {
      NP R = n->r;
      n->push();
      R->push();
      n->r = R->l;
      R->l = n;
      R->level++;
      n->update();
      R->update();
      return R;
    }
    return n;
  }

  static NP leftdown(NP n) {
    assert(n->l->level < n->level);
    if (n->l->level == n->level - 1)
      return n;
    n->level--;
    if (n->r->level == n->level) {
      n = pull(n);
    } else {
      n->r->level--;
      n->r = skew(n->r);
      n->r->r = skew(n->r->r);
      n = pull(n);
      n->r = pull(n->r);
    }
    return n;
  }
  static NP rightdown(NP n) {
    assert(n->r->level <= n->level);
    if (n->r->level >= n->level - 1)
      return n;
    n->level--;
    n = skew(n);
    n->r = skew(n->r);
    n = pull(n);
    return n;
  }
  static NP superleftdown(NP n) {
    if (n->l->level == n->level - 1)
      return n;
    if (n->level != n->r->level && n->r->level != n->r->r->level) {
      n->level--;
      return superleftdown(n);
    }
    n = leftdown(n);
    n->l = superleftdown(n->l);
    n = leftdown(n);
    return n;
  }
  static NP superrightdown(NP n) {
    if (n->r->level >= n->level - 1)
      return n;
    n = rightdown(n);
    n->r = superrightdown(n->r);
    n = rightdown(n);
    return n;
  }

  static NP insert(NP n, int k, D x) {
    if (n == last) {
      assert(k == 0);
      return Node::make(x);
    }
    n->push();
    if (k <= n->l->sz) {
      n->l = insert(n->l, k, x);
      n->update();
    } else {
      n->r = insert(n->r, k - (n->l->sz + 1), x);
      n->update();
    }
    n = skew(n);
    n = pull(n);
    return n;
  }
  // pair<0?????????????´?,0?????????????´??????????????????¨>
  static pair<NP, NP> at0_with_remove(NP n) {
    n->push();
    if (n->l == last) {
      return {n, n->r};
    }
    auto x = at0_with_remove(n->l);
    n->l = x.second;
    n->update();
    x.second = leftdown(n);
    return x;
  }
  static NP remove(NP n, int k) {
    assert(n != last);
    n->push();
    if (k == n->l->sz) {
      if (n->level == 1) {
        return n->r;
      }
      auto x = at0_with_remove(n->r);
      NP nn = x.first;
      nn->push();
      nn->l = n->l;
      nn->r = x.second;
      nn->level = n->level;
      nn->update();
      return rightdown(nn);
    }
    if (k < n->l->sz) {
      n->l = remove(n->l, k);
      n->update();
      return leftdown(n);
    } else {
      n->r = remove(n->r, k - (n->l->sz + 1));
      n->update();
      return rightdown(n);
    }
  }
  static NP merge(NP l, NP r) {
    if (l == last)
      return r;
    if (r == last)
      return l;
    if (l->level == r->level) {
      auto x = at0_with_remove(r);
      NP n = x.first;
      n->push();
      n->r = x.second;
      n->l = l;
      n->level = l->level + 1;
      n->update();
      return rightdown(n);
    }
    NP n;
    l->push();
    r->push();
    if (l->level > r->level) {
      l->push();
      l->r = merge(l->r, r);
      l->update();
      n = l;
    } else {
      r->push();
      r->l = merge(l, r->l);
      r->update();
      n = r;
    }
    n = skew(n);
    n = pull(n);
    return n;
  }
  static pair<NP, NP> split(NP n, int k) {
    if (n == last)
      return {last, last};
    n->push();
    if (k <= n->l->sz) {
      auto y = split(n->l, k);
      n->l = y.second;
      n->update();
      n = superleftdown(n);
      y.second = n;
      return y;
    } else {
      auto y = split(n->r, k - (n->l->sz + 1));
      n->r = y.first;
      n->update();
      n = superrightdown(n);
      y.first = n;
      return y;
    }
  }
};
template <class D, class C>
typename AAMSet<D, C>::Node AAMSet<D, C>::last_d = AAMSet<D, C>::Node();
template <class D, class C>
typename AAMSet<D, C>::NP AAMSet<D, C>::last = &AAMSet<D, C>::last_d;

/*
?????¶????????§??????????????????
*/

template <int S> struct StarrySkyTree {
  typedef int D;
  static const int N = 1 << S;
  AAMSet<int> seg[2 * N];
  int sz[2 * N];
  StarrySkyTree() {
    for (int i = 2 * N - 1; i >= N; i--) {
      sz[i] = 1;
    }
    for (int i = N - 1; i >= 1; i--) {
      sz[i] = sz[i * 2] + sz[i * 2 + 1];
    }
  }
  void init() {
    for (int i = 1; i < 2 * N; i++) {
      seg[i] = AAMSet<int>();
    }
  }

  void update(int k) {
    assert(1 <= k && k < N);
    seg[k] = max(seg[k * 2], seg[k * 2 + 1]);
  }
  void add(int k, D x) {
    k += N;
    seg[k].insert(x);
    while (k > 1) {
      k /= 2;
      seg[k].insert(x);
    }
  }

  D get(int a, int b, D x, int k = 1) {

    if (sz[k] <= a || b <= 0)
      return 0;
    if (a <= 0 && sz[k] <= b)
      return seg[k].lb(x);
    D dl = get(a, b, x, k * 2);
    D dr = get(a - sz[k] / 2, b - sz[k] / 2, x, k * 2 + 1);
    return dl + dr;
  }
};

StarrySkyTree<17> st;
int x[1 << 17];

int main() {
  st.init();
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> x[i];
    st.add(i, x[i]);
  }
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int l, r, e;
    cin >> l >> r >> e;
    l--;
    int mi = min(x[l], x[r - 1]);
    int ma = max(x[l], x[r - 1]);
    mi -= e;
    ma += e + 1;
    int res = st.get(l, r, mi) + ((r - l) - st.get(l, r, ma));
    cout << res << endl;
  }
  return 0;
}