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

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

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

template <typename M> class LazySegmentTree {
  using T = typename M::type;
  using func_t = function<T(T, T)>;
  const int n;
  vector<T> data, lazy;
  int size(int n) {
    int res = 1;
    while (res < n)
      res <<= 1;
    return res;
  }
  void push(int node) {
    if (lazy[node] == M::id2())
      return;
    if (node < n) {
      lazy[node * 2] = M::op2(lazy[node * 2], lazy[node]);
      lazy[node * 2 + 1] = M::op2(lazy[node * 2 + 1], lazy[node]);
    }
    data[node] = M::op2(data[node], lazy[node]);
    lazy[node] = M::id2();
  }
  void suc(int l, int r, int node, int lb, int ub, T val) {
    if (ub <= l || r <= lb)
      return;
    push(node);
    if (l <= lb && ub <= r) {
      lazy[node] = val;
      return;
    }
    int c = (lb + ub) / 2;
    suc(l, r, node * 2, lb, c, val);
    suc(l, r, node * 2 + 1, c, ub, val);
    data[node] = M::op1(M::op2(data[node * 2], lazy[node * 2]),
                        M::op2(data[node * 2 + 1], lazy[node * 2 + 1]));
  }
  T sub(int l, int r, int node, int lb, int ub) {
    if (ub <= l || r <= lb)
      return M::id1();
    push(node);
    if (l <= lb && ub <= r) {
      return data[node];
    }
    int c = (lb + ub) / 2;
    return M::op1(sub(l, r, node * 2, lb, c), sub(l, r, node * 2 + 1, c, ub));
  }

public:
  LazySegmentTree(int n_)
      : n(size(n_)), data(n * 2, M::id1()), lazy(n * 2, M::id2()) {}
  void update(int l, int r, T val) { suc(l, r + 1, 1, 0, n, val); }
  T find(int l, int r) { return sub(l, r + 1, 1, 0, n); }
};

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n, q, com, x, y, val;
  cin >> n >> q;
  LazySegmentTree<RMQ> st(n);
  while (q--) {
    cin >> com >> x >> y;
    if (com) {
      printf("%d\\n", st.find(x, y));
    } else {
      cin >> val;
      st.update(x, y, val);
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

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

const function<int(int, int)> minQ = [](int l, int r) { return min(l, r); };

template <typename T> class node {
public:
  T val, lazy;
  node<T> *l, *r;
  node() {}
  node(T val_, T lazy_, node<T> *l_ = nullptr, node<T> *r_ = nullptr)
      : val(val_), lazy(lazy_), l(l_), r(r_) {}
  void init(T val_, T lazy_, node<T> *l_ = nullptr, node<T> *r_ = nullptr) {
    val = val_;
    lazy = lazy_;
    l = l_;
    r = r_;
  }
};

template <typename T> class SaikyoSegmentTree {
  using func_t = function<T(T, T)>;
  const ll n;
  const T id1, id2;
  func_t merge1, merge2;
  vector<node<T> *> root;
  vector<node<T>> pool;
  int it;
  ll size(ll n) {
    ll res = 1;
    while (res < n)
      res <<= 1;
    return res;
  }
  node<T> *new_node() {
    pool[it].init(id1, id2);
    return &pool[it++];
  }
  node<T> *fix(node<T> *t) {
    pool[it] = *t;
    return &pool[it++];
  }
  node<T> *push(node<T> *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 = merge2(t->l->lazy, t->lazy);
      t->r->lazy = merge2(t->r->lazy, t->lazy);
    }
    t->val = merge2(t->val, t->lazy);
    t->lazy = id2;
    return t;
  }
  node<T> *suc(ll l, ll r, node<T> *t, ll lb, ll ub, T val) {
    if (ub <= l || r <= lb)
      return t;
    if (t == nullptr)
      t = new_node();
    if (l <= lb && ub <= r) {
      t->lazy = merge2(t->lazy, val);
      return t;
    }
    t = push(t, lb, ub);
    int c = (lb + ub) / 2;
    t->l = suc(l, r, t->l, lb, c, val);
    t->r = suc(l, r, t->r, c, ub, val);
    t->val = merge1(t->l == nullptr ? id1 : merge2(t->l->val, t->l->lazy),
                    t->r == nullptr ? id1 : merge2(t->r->val, t->r->lazy));
    return t;
  }
  node<T> *sub(ll l, ll r, node<T> *t, ll lb, ll ub, T &res) {
    if (t == nullptr || ub <= l || r <= lb)
      return t;
    t = push(t, lb, ub);
    if (l <= lb && ub <= r) {
      res = merge1(res, t->val);
      return t;
    }
    int c = (lb + ub) / 2;
    t->l = sub(l, r, t->l, lb, c, res);
    t->r = sub(l, r, t->r, c, ub, res);
    return t;
  }

public:
  SaikyoSegmentTree(ll n_, T id1_, T id2_, func_t merge1_, func_t merge2_,
                    int PMAX = 1.4e7)
      : n(size(n_)), id1(id1_), id2(id2_), merge1(merge1_), merge2(merge2_),
        root(1, nullptr), pool(PMAX), it(0) {}
  void update(ll l, ll r, T 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));
  }
  T find(ll l, ll r, int rt = -1) {
    if (rt == -1)
      rt = root.size() - 1;
    assert(0 <= rt && rt < (int)root.size());
    T res = id1;
    root.push_back(sub(l, r + 1, root[rt], 0, n, res));
    return res;
  }
  int getversion() { return root.size() - 1; }
};

int main() {
  cin.sync_with_stdio(false);
  int n, q, com, s, t, x;
  cin >> n >> q;
  SaikyoSegmentTree<int> lst(n, INT_MAX, -1, minQ,
                             [](int l, int r) { return r != -1 ? r : l; });
  while (q--) {
    cin >> com;
    if (com) {
      cin >> s >> t;
      printf("%d\\n", lst.find(s, t));
    } else {
      cin >> s >> t >> x;
      lst.update(s, t, x);
    }
  }
  return 0;
}