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

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

using Value = int;
const Value INI = INT_MAX;
struct Node {
  Value
      sum; //??´??°????????????.
           //?????????????????§??????????????????????????¨????????????????????????????????????.
  Value lazy; //?????¶???????????????????????????????????????
  Node() : sum(0) { lazy = 0; }
};
struct lazy_segtree {
  int N;
  vector<Node> dat;
  lazy_segtree(int n) : N(1) {
    while (N < n)
      N *= 2;
    dat.resize(2 * N);
  }

  void lazy_func(const int k, const int a, const int b) {
    dat[k].sum += dat[k].lazy * (b - a + 1);
  }

  Value connect(const Value l, const Value r) { return l + r; }

  // inline??????????????¨??§???????????¨????????????!(??????)
  inline void lazy_evaluate_node(int k, int a, int b) {
    lazy_func(k, a, b);
    if (k <
        N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§.
             // ???????????????????????????????????¬???????????¨??????.
      dat[2 * k].lazy +=
          dat[k].lazy; //?¬???????????????¬??????????????£?????????.
      dat[2 * k + 1].lazy += dat[k].lazy;
    }
    dat[k].lazy = 0;
  }

  inline void update_node(
      int k) { // k???????????¢?????????????????????????????¨?????????.
               // ????????\\????????¨????????????????????????????????????????????????????????§if???????????????.
    dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);
  }

  // update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
  void update(int l, int r, Value v, int k = 1, int a = 1, int b = -1) {
    if (b == -1)
      b = N;
    if (l < 0 || r < 0)
      assert(false);
    lazy_evaluate_node(
        k, a,
        b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\\?.

    if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
      return;
    if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
      dat[k].lazy += v;
      lazy_evaluate_node(
          k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
      return;
    }

    int m = (a + b) / 2;
    update(l, r, v, 2 * k, a, m);
    update(l, r, v, 2 * k + 1, m + 1, b);
    update_node(k);
  }

  // get(l,r) := [l,r]?????????????????¨?????????????????????.
  // ?????????1-indexed.
  Value get(int l, int r, int k = 1, int a = 1, int b = -1) {
    if (b == -1)
      b = N;

    if (l < 0 || r < 0)
      assert(false);
    lazy_evaluate_node(
        k, a,
        b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\\?.

    if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
      return 0;

    if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
      return dat[k].sum;
    }

    int m = (a + b) / 2;
    Value vl = get(l, r, 2 * k, a, m);
    Value vr = get(l, r, 2 * k + 1, m + 1, b);
    update_node(k);
    return connect(vl, vr);
  }
};
namespace perseg {

struct permanent_segtree {
  Value val;
  Value lazy;
  int l, r;
  vector<shared_ptr<permanent_segtree>> chs;

public:
  permanent_segtree(const int size_)
      : val(INI), lazy(INI), l(0), r(size_), chs(2, nullptr) {}
  permanent_segtree(const Value &val_, const int l_, const int r_)
      : val(val_), lazy(INI), l(l_), r(r_), chs(2, nullptr) {}
  permanent_segtree(const permanent_segtree &tree_)
      : val(tree_.val), lazy(tree_.lazy), l(tree_.l), r(tree_.r),
        chs(tree_.chs) {}
  void lazy_func() {
    if (lazy != INI) {
      val = lazy;
    }
  }
  Value update_lazy(int lazy_from, int lazy_to) {
    if (lazy_to != INI) {

      return lazy_to;
    } else {
      return lazy_from;
    }
  }
  void lazy_evaluate_node() {
    lazy_func();
    if (l + 1 != r) {
      for (int i = 0; i < 2; ++i) {
        getch(i)->lazy = update_lazy(getch(i)->lazy, lazy);
      }
    }
    lazy = INI;
  }
  shared_ptr<permanent_segtree> getch(const int num_) {
    const int amid = (l + r) / 2;

    if (chs[num_] == nullptr) {
      if (num_ == 0) {
        chs[0] = make_shared<permanent_segtree>(INI, l, amid);
      } else {
        chs[1] = make_shared<permanent_segtree>(INI, amid, r);
      }
    }
    return chs[num_];
  }
  Value eval_value(const Value &value_l, const Value &value_r) const {
    return min(value_l, value_r);
  }
  // min [a, b)
  Value query(int a, int b, int k) {
    lazy_evaluate_node();
    if (r <= a or b <= l)
      return INI;
    if (a <= l and r <= b)
      return val;
    const int m = (l + r) / 2;
    const Value al(getch(0)->query(a, b, k));
    const Value ar(getch(1)->query(a, b, k));
    return eval_value(al, ar);
  }
};

shared_ptr<permanent_segtree>
immutable_update(const shared_ptr<permanent_segtree> &tree, const int l,
                 const int r, const Value a) {
  tree->lazy_evaluate_node();
  if (tree->r <= l || r <= tree->l) {
    return tree;
  } else if (l <= tree->l && tree->r <= r) {
    shared_ptr<permanent_segtree> new_tree(
        make_shared<permanent_segtree>(INI, tree->l, tree->r));
    new_tree->lazy = new_tree->update_lazy(new_tree->lazy, a);
    new_tree->lazy_evaluate_node();
    return new_tree;
  } else {
    shared_ptr<permanent_segtree> copy_tree =
        (make_shared<permanent_segtree>(*tree));
    assert(tree->l + 1 < tree->r);
    copy_tree->chs[0] = immutable_update(tree->getch(0), l, r, a);
    copy_tree->chs[1] = immutable_update(tree->getch(1), l, r, a);
    copy_tree->val = copy_tree->eval_value(copy_tree->getch(0)->val,
                                           copy_tree->getch(1)->val);

    return copy_tree;
  }
}
} // namespace perseg

int main() {
  using namespace perseg;
  vector<shared_ptr<permanent_segtree>> trees(1, nullptr);
  trees[0] = make_shared<permanent_segtree>(1 << 17);
  int N, Q;
  cin >> N >> Q;
  int now = 0;
  vector<tuple<int, int, int>> qs;
  bool flag = false;
  for (int i = 0; i < Q; ++i) {

    int com;
    cin >> com;
    if (com) {
      int s, t;
      cin >> s >> t;
      qs.push_back(make_tuple(now, s, t));
      flag = true;
      int anow, x, y;
      tie(anow, x, y) = qs.back();
      int ans = trees[anow]->query(x, y + 1, 100);
      cout << ans << endl;
    } else {
      int s, t, x;
      cin >> s >> t >> x;
      if (flag) {
        trees.push_back(immutable_update(trees[now], s, t + 1, x));
        now++;
        flag = false;
        trees[trees.size() - 2] = nullptr;
      } else {
        trees.back() = immutable_update(trees[now], s, t + 1, x);
      }
    }
  }

  return 0;
}

Error: MLE

Fixed submission:

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

using Value = int;
const Value INI = INT_MAX;
struct Node {
  Value
      sum; //??´??°????????????.
           //?????????????????§??????????????????????????¨????????????????????????????????????.
  Value lazy; //?????¶???????????????????????????????????????
  Node() : sum(0) { lazy = 0; }
};
struct lazy_segtree {
  int N;
  vector<Node> dat;
  lazy_segtree(int n) : N(1) {
    while (N < n)
      N *= 2;
    dat.resize(2 * N);
  }

  void lazy_func(const int k, const int a, const int b) {
    dat[k].sum += dat[k].lazy * (b - a + 1);
  }

  Value connect(const Value l, const Value r) { return l + r; }

  // inline??????????????¨??§???????????¨????????????!(??????)
  inline void lazy_evaluate_node(int k, int a, int b) {
    lazy_func(k, a, b);
    if (k <
        N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§.
             // ???????????????????????????????????¬???????????¨??????.
      dat[2 * k].lazy +=
          dat[k].lazy; //?¬???????????????¬??????????????£?????????.
      dat[2 * k + 1].lazy += dat[k].lazy;
    }
    dat[k].lazy = 0;
  }

  inline void update_node(
      int k) { // k???????????¢?????????????????????????????¨?????????.
               // ????????\\????????¨????????????????????????????????????????????????????????§if???????????????.
    dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);
  }

  // update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
  void update(int l, int r, Value v, int k = 1, int a = 1, int b = -1) {
    if (b == -1)
      b = N;
    if (l < 0 || r < 0)
      assert(false);
    lazy_evaluate_node(
        k, a,
        b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\\?.

    if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
      return;
    if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
      dat[k].lazy += v;
      lazy_evaluate_node(
          k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
      return;
    }

    int m = (a + b) / 2;
    update(l, r, v, 2 * k, a, m);
    update(l, r, v, 2 * k + 1, m + 1, b);
    update_node(k);
  }

  // get(l,r) := [l,r]?????????????????¨?????????????????????.
  // ?????????1-indexed.
  Value get(int l, int r, int k = 1, int a = 1, int b = -1) {
    if (b == -1)
      b = N;

    if (l < 0 || r < 0)
      assert(false);
    lazy_evaluate_node(
        k, a,
        b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\\?.

    if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
      return 0;

    if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
      return dat[k].sum;
    }

    int m = (a + b) / 2;
    Value vl = get(l, r, 2 * k, a, m);
    Value vr = get(l, r, 2 * k + 1, m + 1, b);
    update_node(k);
    return connect(vl, vr);
  }
};
namespace perseg {

struct permanent_segtree {
  Value val;
  Value lazy;
  int l, r;
  vector<shared_ptr<permanent_segtree>> chs;

public:
  permanent_segtree(const int size_)
      : val(INI), lazy(INI), l(0), r(size_), chs(2, nullptr) {}
  permanent_segtree(const Value &val_, const int l_, const int r_)
      : val(val_), lazy(INI), l(l_), r(r_), chs(2, nullptr) {}
  permanent_segtree(const permanent_segtree &tree_)
      : val(tree_.val), lazy(tree_.lazy), l(tree_.l), r(tree_.r),
        chs(tree_.chs) {}
  void lazy_func() {
    if (lazy != INI) {
      val = lazy;
    }
  }
  Value update_lazy(int lazy_from, int lazy_to) {
    if (lazy_to != INI) {

      return lazy_to;
    } else {
      return lazy_from;
    }
  }
  void lazy_evaluate_node() {
    lazy_func();
    if (l + 1 != r) {
      for (int i = 0; i < 2; ++i) {
        getch(i)->lazy = update_lazy(getch(i)->lazy, lazy);
      }
    }
    lazy = INI;
  }
  shared_ptr<permanent_segtree> getch(const int num_) {
    const int amid = (l + r) / 2;

    if (chs[num_] == nullptr) {
      if (num_ == 0) {
        chs[0] = make_shared<permanent_segtree>(INI, l, amid);
      } else {
        chs[1] = make_shared<permanent_segtree>(INI, amid, r);
      }
    }
    return chs[num_];
  }
  Value eval_value(const Value &value_l, const Value &value_r) const {
    return min(value_l, value_r);
  }
  // min [a, b)
  Value query(int a, int b, int k) {
    lazy_evaluate_node();
    if (r <= a or b <= l)
      return INI;
    if (a <= l and r <= b)
      return val;
    const int m = (l + r) / 2;
    const Value al(getch(0)->query(a, b, k));
    const Value ar(getch(1)->query(a, b, k));
    return eval_value(al, ar);
  }
};

shared_ptr<permanent_segtree>
immutable_update(const shared_ptr<permanent_segtree> &tree, const int l,
                 const int r, const Value a) {
  tree->lazy_evaluate_node();
  if (tree->r <= l || r <= tree->l) {
    return tree;
  } else if (l <= tree->l && tree->r <= r) {
    shared_ptr<permanent_segtree> new_tree(
        make_shared<permanent_segtree>(INI, tree->l, tree->r));
    new_tree->lazy = new_tree->update_lazy(new_tree->lazy, a);
    new_tree->lazy_evaluate_node();
    return new_tree;
  } else {
    shared_ptr<permanent_segtree> copy_tree =
        (make_shared<permanent_segtree>(*tree));
    assert(tree->l + 1 < tree->r);
    copy_tree->chs[0] = immutable_update(tree->getch(0), l, r, a);
    copy_tree->chs[1] = immutable_update(tree->getch(1), l, r, a);
    copy_tree->val = copy_tree->eval_value(copy_tree->getch(0)->val,
                                           copy_tree->getch(1)->val);

    return copy_tree;
  }
}
} // namespace perseg

int main() {
  using namespace perseg;
  vector<shared_ptr<permanent_segtree>> trees(1, nullptr);
  trees[0] = make_shared<permanent_segtree>(1 << 17);
  int N, Q;
  cin >> N >> Q;
  int now = 0;
  vector<tuple<int, int, int>> qs;
  bool flag = false;
  for (int i = 0; i < Q; ++i) {

    int com;
    cin >> com;
    if (com) {
      int s, t;
      cin >> s >> t;
      qs.push_back(make_tuple(now, s, t));
      flag = true;
    } else {
      int s, t, x;
      cin >> s >> t >> x;
      if (flag) {
        trees.push_back(immutable_update(trees[now], s, t + 1, x));
        now++;
        flag = false;
      } else {
        trees.back() = immutable_update(trees[now], s, t + 1, x);
      }
    }
  }
  for (int i = 0; i < qs.size(); ++i) {
    int anow, x, y;
    tie(anow, x, y) = qs[i];
    int ans = trees[anow]->query(x, y + 1, 100);
    cout << ans << endl;
  }

  return 0;
}