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

#include <functional>
#include <stdio.h>
#include <vector>

template <typename Monoid, typename OperatorMonoid = Monoid>
class lazy_segment_tree {
  using value_type = Monoid;
  using operator_type = OperatorMonoid;
  using size_type = size_t;

  using F = std::function<value_type(value_type, value_type)>;
  using G = std::function<value_type(value_type, operator_type, int, int)>;
  using H = std::function<operator_type(operator_type, operator_type)>;

  size_type size_;
  size_type height_;

  F f;
  G g;
  H h;
  value_type id;
  operator_type id_op;
  std::vector<value_type> data;
  std::vector<operator_type> lazy;
  std::vector<size_type> depth;

  const size_type get_height(const size_type &size) const {
    size_type height = 1;
    while (1 << height < size)
      height++;
    return height;
  }
  const size_type base_size() const { return 1 << height_; }
  const value_type reflect(const size_type &k) {
    if (lazy[k] == id_op)
      return data[k];
    int l = (k - (1 << depth[k])) * (base_size() >> depth[k]);
    int r = l + (base_size() >> depth[k]);
    return g(data[k], lazy[k], l, r);
  }
  void eval(const size_type &k) {
    if (lazy[k] == id_op)
      return;
    lazy[k << 1 ^ 0] = h(lazy[k << 1 ^ 0], lazy[k]);
    lazy[k << 1 ^ 1] = h(lazy[k << 1 ^ 1], lazy[k]);
    data[k] = reflect(k);
    lazy[k] = id_op;
  }
  void thrust(const size_type &k) {
    for (int i = height_; i; i--)
      eval(k >> i);
  }
  void recalc(size_type k) {
    while (k >>= 1)
      data[k] = f(reflect(k << 1 ^ 0), reflect(k << 1 ^ 1));
  }

public:
  lazy_segment_tree() {}
  lazy_segment_tree(int n, const F &f, const G &g, const H &h,
                    const value_type &id, const operator_type &id_op)
      : size_(n), f(f), g(g), h(h), id(id), id_op(id_op) {
    height_ = get_height(size_);
    data.assign(base_size() << 1, id);
    lazy.assign(base_size() << 1, id_op);
    depth.assign(base_size() << 1, 0);
    for (int i = 0; i < height_ + 1; i++)
      for (int j = (1 << i); j < (1 << (i + 1)); j++)
        depth[j] = i;
  }
  void update(size_type a, size_type b, operator_type x) {
    thrust(a += base_size());
    thrust(b += base_size() - 1);
    for (size_type l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), l++;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }
  void change(size_type k, const value_type x) {
    thrust(k += base_size());
    data[k] = x;
    lazy[k] = id_op;
    recalc(k);
  }
  const value_type fold(size_type a, size_type b) {
    thrust(a += base_size());
    thrust(b += base_size() - 1);

    value_type left_value = id;
    value_type right_value = id;
    for (size_type l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        left_value = f(left_value, reflect(l++));
      if (r & 1)
        right_value = f(reflect(--r), right_value);
    }
    return f(left_value, right_value);
  }

  const value_type operator[](const size_type &k) { return fold(k, k + 1); }
};

using i64 = long long;

int main() {
  int n, q;
  scanf("%d%d", &n, &q);

  auto f = [](i64 a, i64 b) { return a + b; };
  auto g = [](i64 a, i64 b, int l, int r) { return a + b * (i64)(r - l); };
  auto h = [](i64 a, i64 b) { return a + b; };
  lazy_segment_tree<i64> seg(n, f, g, h, 0, 0);

  while (q--) {
    int type;
    scanf("%d", &type);

    if (type == 0) {
      int s, t, x;
      scanf("%d%d%d", &s, &t, &x);

      seg.update(s - 1, t, x);
    } else if (type == 1) {
      int s, t;
      scanf("%d%d", &s, &t);

      printf("%lld\\n", seg.fold(s - 1, t));
    }
  }

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, a, b) for (int i = (a); i < (b); i++)
#define RREP(i, a, b) for (int i = (a); i >= (b); i--)
#define pq priority_queue
#define P pair<int, int>
#define P2 pair<int, P>
#define P3 pair<int, P2>
typedef long long ll;
typedef long double ld;
using namespace std;
const int INF = 1e9, MOD = 1e9 + 7,
          around[] = {0, 1, 1, -1, -1, 0, -1, 1, 0, 0};
const int vx[] = {1, 0, -1, 0}, vy[] = {0, 1, 0, -1};
const ld PI = abs(acos(-1));
const int sqrtN = 512;
const int logN = 32;
const ll LINF = 1e18;

struct Node {
  ll data, lazy;

  Node(ll data, ll lazy) : data(data), lazy(lazy) {}
  Node operator*(const ll r) { return Node(data, lazy * r); }
  Node operator*(const Node r) { return Node(data + r.data, lazy); }
  Node operator+(const Node r) { return Node(data, lazy + r.lazy); }
  Node operator-(const Node r) { return Node(data + r.lazy, 0); }
} e(0, 0);

struct LazySegmentTree {
  vector<Node> seg;
  int sz = 1;

  LazySegmentTree(int n) {
    while (sz < n)
      sz *= 2;
    seg.assign(sz * 2, e);
  }

  void update(int k, int x) {
    k += sz - 1;
    seg[k] = Node(x, 0);
    while (k) {
      k = (k - 1) / 2;
      seg[k] = seg[2 * k + 1] * seg[2 * k + 2];
    }
  }

  void push(int k, ll len) {
    if (k < sz) {
      seg[2 * k + 1] = seg[2 * k + 1] + seg[k];
      seg[2 * k + 2] = seg[2 * k + 2] + seg[k];
    }

    seg[k] = seg[k] - seg[k] * len;
  }

  void add(int a, int b, ll x) { add(a, b, 0, 0, sz, Node(0, x)); }

  void add(int a, int b, int k, int l, int r, Node x) {
    push(k, r - l);
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      seg[k] = seg[k] + x;
      push(k, r - l);
      return;
    }

    add(a, b, 2 * k + 1, l, (l + r) / 2, x);
    add(a, b, 2 * k + 2, (l + r) / 2, r, x);
    seg[k] = seg[2 * k + 1] * seg[2 * k + 2];
  }

  ll get(int a, int b) { return get(a, b, 0, 0, sz).data; }

  Node get(int a, int b, int k, int l, int r) {
    push(k, r - l);
    if (b <= l || r <= a)
      return e;
    if (a <= l && r <= b)
      return seg[k];

    return get(a, b, 2 * k + 1, l, (l + r) / 2) *
           get(a, b, 2 * k + 2, (l + r) / 2, r);
  }
};

int main() {
  int n, q;
  cin >> n >> q;
  LazySegmentTree seg(n);

  for (int i = 0; i < q; i++) {
    int a;
    cin >> a;

    if (a == 0) {
      int b, c;
      cin >> a >> b >> c;
      seg.add(a - 1, b, c);
    } else if (a == 1) {
      int b;
      cin >> a >> b;
      cout << seg.get(a - 1, b) << endl;
    }
  }

  return 0;
}