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

#include <bits/stdc++.h>
using namespace std;

struct RMQ {
  using type = int;
  static type id() { return INT_MAX; }
  static type op(const type &l, const type &r) { return min(l, r); }
};

class seg_node {
public:
  using M = RMQ;
  using T = typename M::type;
  using U = int;

  T val;

private:
  bool flag;
  U lazy;

public:
  seg_node() : val(M::id()), flag(false) {}
  void init(const T &v) { val = v; }
  void init(const seg_node &l, const seg_node &r) { val = M::op(l.val, r.val); }
  void update(U v) {
    val = lazy = v;
    flag = true;
  }
  void push(seg_node &l, seg_node &r) {
    if (!flag)
      return;
    l.update(lazy);
    r.update(lazy);
    flag = false;
  }
  bool is_updated() const { return flag; }
};

class segment_tree {
  using M = typename seg_node::M;
  using T = typename seg_node::T;
  using U = typename seg_node::U;
  const int h, n;
  vector<seg_node> data;
  void init() {
    for (int i = n - 1; i >= 1; i--) {
      data[i].init(data[i << 1], data[(i << 1) | 1]);
    }
  }
  void push(int node) {
    data[node].push(data[node << 1], data[(node << 1) | 1]);
  }
  void update(int node) {
    data[node].val = M::op(data[node << 1].val, data[(node << 1) | 1].val);
  }

public:
  segment_tree(int n_) : h(ceil(log2(n_))), n(1 << h), data(n * 2) {}
  segment_tree(int n_, T v1) : h(ceil(log2(n_))), n(1 << h), data(n * 2) {
    for (int i = 0; i < n_; i++) {
      data[i + n].init(v1);
    }
    init();
  }
  segment_tree(const vector<T> &data_)
      : h(ceil(log2(data_.size()))), n(1 << h), data(n * 2) {
    for (int i = 0; i < (int)data_.size(); i++) {
      data[i + n].init(data_[i]);
    }
    init();
  }
  void update(int l, int r, U val) {
    l += n, r += n;
    for (int i = h; i > 0; i--)
      push(l >> i), push(r >> i);
    int tl = l, tr = r;
    r++;
    while (l < r) {
      if (l & 1)
        data[l++].update(val);
      if (r & 1)
        data[--r].update(val);
      l >>= 1;
      r >>= 1;
    }
    while (tl >>= 1, tr >>= 1, tl) {
      if (!data[tl].is_updated())
        update(tl);
      if (!data[tr].is_updated())
        update(tr);
    }
  }
  T find(int l, int r) {
    l += n, r += n;
    for (int i = h; i > 0; i--)
      push(l >> i), push(r >> i);
    r++;
    T res1 = M::id(), res2 = M::id();
    while (l < r) {
      if (l & 1)
        res1 = M::op(res1, data[l++].val);
      if (r & 1)
        res2 = M::op(data[--r].val, res2);
      l >>= 1;
      r >>= 1;
    }
    return M::op(res1, res2);
  }
};

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int N, M, Q;
  cin >> N >> M >> Q;
  vector<vector<int>> dab(M, vector<int>(3));
  vector<int> ds;
  for (int i = 0; i < M; i++) {
    cin >> dab[i][0] >> dab[i][1] >> dab[i][2];
    dab[i][1]--, dab[i][2] -= 2;
    ds.push_back(dab[i][0]);
  }
  vector<int> res(Q);
  vector<vector<int>> est(Q, vector<int>(4));
  for (int i = 0; i < Q; i++) {
    cin >> est[i][0] >> est[i][1] >> est[i][2];
    est[i][1]--, est[i][2] -= 2;
    est[i][3] = i;
    ds.push_back(est[i][0]);
  }
  sort(ds.begin(), ds.end());
  ds.erase(unique(ds.begin(), ds.end()), ds.end());
  sort(dab.begin(), dab.end());
  sort(est.begin(), est.end());
  int x = ds.size();
  segment_tree st(N);
  st.update(0, N - 1, 0);
  for (int i = 0, j = 0, k = 0; i < x; i++) {
    while (j < Q && est[j][0] <= ds[i]) {
      res[est[j][3]] = st.find(est[j][1], est[j][2]);
      j++;
    }
    while (k < M && dab[k][0] <= ds[i]) {
      st.update(dab[k][1], dab[k][2], 1);
      k++;
    }
  }
  for (int i = 0; i < Q; i++) {
    puts(res[i] ? "Yes" : "No");
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

struct RURM {
  using t1 = int;
  using t2 = int;
  static t1 id1() { return INT_MAX; }
  static t2 id2() { return -1; }
  static t1 op1(const t1 &l, const t1 &r) { return min(l, r); }
  static t1 op2(const t1 &l, const t2 &r) { return r != id2() ? r : l; }
  static t2 op3(const t2 &l, const t2 &r) { return r != id2() ? r : l; }
};

template <typename M> class node {
  using T1 = typename M::t1;
  using T2 = typename M::t2;

public:
  T1 val;
  T2 lazy;
  node<M> *l, *r;
  node() {}
  void init(T1 val_, T2 lazy_, node<M> *l_ = nullptr, node<M> *r_ = nullptr) {
    val = val_;
    lazy = lazy_;
    l = l_;
    r = r_;
  }
};

template <typename M> class SaikyoSegmentTree {
  using T1 = typename M::t1;
  using T2 = typename M::t2;
  const ll n;
  vector<node<M> *> root;
  vector<node<M>> pool;
  int it;
  ll size(ll n) {
    ll res = 1;
    while (res < n)
      res <<= 1;
    return res;
  }
  node<M> *new_node() {
    pool[it].init(M::id1(), M::id2());
    return &pool[it++];
  }
  node<M> *fix(node<M> *t) {
    pool[it] = *t;
    return &pool[it++];
  }
  node<M> *push(node<M> *t, ll lb, ll ub) {
    t = fix(t);
    if (lb + 1 < ub) {
      if (t->l == nullptr)
        t->l = new_node();
      else
        t->l = fix(t->l);
      if (t->r == nullptr)
        t->r = new_node();
      else
        t->r = fix(t->r);
      t->l->lazy = M::op3(t->l->lazy, t->lazy);
      t->r->lazy = M::op3(t->r->lazy, t->lazy);
    }
    t->val = M::op2(t->val, t->lazy);
    t->lazy = M::id2();
    return t;
  }
  node<M> *suc(ll l, ll r, node<M> *t, ll lb, ll ub, T2 val) {
    if (ub <= l || r <= lb)
      return t;
    if (t == nullptr)
      t = new_node();
    if (l <= lb && ub <= r) {
      t->lazy = M::op3(t->lazy, val);
      return t;
    }
    t = push(t, lb, ub);
    t->l = suc(l, r, t->l, lb, (lb + ub) / 2, val);
    t->r = suc(l, r, t->r, (lb + ub) / 2, ub, val);
    t->val = M::op1(t->l == nullptr ? M::id1() : M::op2(t->l->val, t->l->lazy),
                    t->r == nullptr ? M::id1() : M::op2(t->r->val, t->r->lazy));
    return t;
  }
  node<M> *sub(ll l, ll r, node<M> *t, ll lb, ll ub, T1 &res) {
    if (t == nullptr || ub <= l || r <= lb)
      return t;
    if (l <= lb && ub <= r) {
      res = M::op1(res, M::op2(t->val, t->lazy));
      return t;
    }
    t = push(t, lb, ub);
    t->l = sub(l, r, t->l, lb, (lb + ub) / 2, res);
    t->r = sub(l, r, t->r, (lb + ub) / 2, ub, res);
    return t;
  }

public:
  SaikyoSegmentTree(ll n_, int PMAX = 2e7)
      : n(size(n_)), root(1, nullptr), pool(PMAX), it(0) {}
  void update(ll l, ll r, T2 val, int rt = -1) {
    if (rt == -1)
      rt = root.size() - 1;
    assert(0 <= rt && rt < (int)root.size());
    root.push_back(suc(l, r + 1, root[rt], 0, n, val));
  }
  T1 find(ll l, ll r, int rt = -1) {
    if (rt == -1)
      rt = root.size() - 1;
    assert(0 <= rt && rt < (int)root.size());
    T1 res = M::id1();
    root.push_back(sub(l, r + 1, root[rt], 0, n, res));
    return res;
  }
  int getversion() { return root.size() - 1; }
};

int main() {
  int N, M, Q;
  cin >> N >> M >> Q;
  vector<vector<int>> dab(M, vector<int>(3));
  vector<int> ds;
  for (int i = 0; i < M; i++) {
    cin >> dab[i][0] >> dab[i][1] >> dab[i][2];
    dab[i][1]--, dab[i][2] -= 2;
    ds.push_back(dab[i][0]);
  }
  sort(ds.begin(), ds.end());
  ds.erase(unique(ds.begin(), ds.end()), ds.end());
  sort(dab.begin(), dab.end());
  SaikyoSegmentTree<RURM> sst(N + 1);
  vector<int> vers(ds.size() + 1);
  sst.update(0, N, 0);
  vers[0] = sst.getversion();
  for (int i = 0, j = 0; i < (int)ds.size(); i++) {
    while (j < M && dab[j][0] <= ds[i]) {
      sst.update(dab[j][1], dab[j][2], 1);
      j++;
    }
    vers[i + 1] = sst.getversion();
  }
  while (Q--) {
    int E, S, T;
    cin >> E >> S >> T;
    E--;
    S--, T -= 2;
    int t = (upper_bound(ds.begin(), ds.end(), E) - ds.begin());
    puts(sst.find(S, T, vers[t]) ? "Yes" : "No");
  }
  return 0;
}