Problem p02350 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
  using P = function<OperatorMonoid(OperatorMonoid, int)>;

  int sz;
  vector<Monoid> seg, lazy;
  const F f;
  const G g;
  const H h;
  const P p;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const P p,
                  const Monoid &M1, const OperatorMonoid OM0)
      : f(f), g(g), h(h), p(p), M1(M1), OM0(OM0) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void propagate(int k, int len) {
    if (lazy[k] != OM0) {
      if (k < sz) {
        lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      }
      seg[k] = g(seg[k], p(lazy[k], len));
      lazy[k] = OM0;
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return seg[k];
    } else if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      propagate(k, r - l);
      return seg[k];
    } else {
      return seg[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
                        update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x) {
    return update(a, b, x, 1, 0, sz);
  }

  Monoid query(int a, int b, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return M1;
    } else if (a <= l && r <= b) {
      return seg[k];
    } else {
      return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
               query(a, b, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid query(int a, int b) { return query(a, b, 1, 0, sz); }

  Monoid operator[](const int &k) { return query(k, k + 1); }
};

int main() {
  int N, Q;
  scanf("%d %d", &N, &Q);

  auto f = [&](int a, int b) { return min(a, b); };
  auto g = [&](int a, int b) { return b < 0 ? a : b; };
  auto p = [&](int a, int b) { return a; };
  LazySegmentTree<int> seg(N, f, g, g, p, INT_MAX, -1);

  while (Q--) {
    int T, X, Y;
    scanf("%d %d %d", &T, &X, &Y);
    if (T == 0) {
      int Z;
      scanf("%d", &Z);
      seg.update(X, Y + 1, Z);
    } else {
      printf("%d\\n", seg.query(X, Y + 1));
    }
  }
}


Error: -6
malloc(): corrupted top size


Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
  using P = function<OperatorMonoid(OperatorMonoid, int)>;

  int sz;
  vector<Monoid> seg, lazy;
  const F f;
  const G g;
  const H h;
  const P p;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const P p,
                  const Monoid &M1, const OperatorMonoid OM0)
      : f(f), g(g), h(h), p(p), M1(M1), OM0(OM0) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void propagate(int k, int len) {
    if (lazy[k] != OM0) {
      lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      seg[k] = g(seg[k], p(lazy[k], len));
      lazy[k] = OM0;
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return seg[k];
    } else if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      propagate(k, r - l);
      return seg[k];
    } else {
      return f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
               update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x) {
    return update(a, b, x, 1, 0, sz);
  }

  Monoid query(int a, int b, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return M1;
    } else if (a <= l && r <= b) {
      return seg[k];
    } else {
      return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
               query(a, b, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid query(int a, int b) { return query(a, b, 1, 0, sz); }

  Monoid operator[](const int &k) { return query(k, k + 1); }
};

int main() {
  int N, Q;
  scanf("%d %d", &N, &Q);

  auto f = [&](int a, int b) { return min(a, b); };
  auto g = [&](int a, int b) { return b; };
  auto p = [&](int a, int b) { return a; };
  LazySegmentTree<int> seg(N, f, g, g, p, INT_MAX, 0);

  while (Q--) {
    int T, X, Y;
    scanf("%d %d %d", &T, &X, &Y);
    if (T == 0) {
      int Z;
      scanf("%d", &Z);
      seg.update(X, Y + 1, Z);
    } else {
      printf("%d\\n", seg.query(X, Y + 1));
    }
  }
}