Problem p02351 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
// const int INF = 1e8;
using namespace std;

struct RAQ {
  using T = long long;
  T operator()(const T &a, const T &b) { return a + b; };
  static constexpr T identity() { return 0; }
};

template <class Monoid> class rangeAddQuery {
private:
  using T = typename Monoid::T;
  Monoid op;
  const int n;
  vector<T> dat, lazy;
  T query(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return op.identity();
    else if (a <= l && r <= b)
      return dat[k] * (r - l) + lazy[k];
    else {
      T res = (min(b, r) - max(a, l)) * dat[k];
      res += query(a, b, k * 2, l, (l + r) / 2);
      res += query(a, b, k * 2 + 1, (l + r) / 2, r);
      return res;
    }
  }
  void add(int a, int b, int k, int l, int r, T x) {
    if (a <= l && r <= b) {
      dat[k] += x;
    } else if (l < b && a < r) {
      lazy[k] += (min(b, r) - max(a, l)) * x;
      add(a, b, k * 2, l, (l + r) / 2, x);
      add(a, b, k * 2 + 1, (l + r) / 2, r, x);
    }
  }
  int power(int n) {
    int res = 1;
    while (n >= res)
      res *= 2;
    return res;
  }

public:
  rangeAddQuery(int n)
      : n(power(n)), dat(4 * n, op.identity()), lazy(4 * n, op.identity()) {}
  rangeAddQuery(const vector<T> &v)
      : n(v.size()), dat(4 * n), lazy(4 * n, op.identity()) {
    copy(begin(v), end(v), begin(dat) + n);
    for (int i = n - 1; i > 0; i--)
      dat[i] = op(dat[2 * i], dat[2 * i + 1]);
  }
  int query(int a, int b) { return query(a, b, 1, 0, n); }
  void add(int s, int t, T x) { add(s, t, 1, 0, n, x); }
  int get(int a) { return query(a, a + 1); };
  void out() {
    rep(i, n * 2) { cout << dat[i + 1] << ' '; }
    cout << endl;
  }
};

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

  rangeAddQuery<RAQ> seg(n);
  rep(i, q) {
    int com;
    cin >> com;
    if (not com) {
      int s, t, x;
      cin >> s >> t >> x;
      // cout << s << ' ' << t << endl;
      seg.add(s - 1, t, x);
    } else {
      int s, t;
      cin >> s >> t;
      assert(seg.query(s - 1, t) >= 0);
      cout << seg.query(s - 1, t) << endl;
    }
    // seg.out();
  }
}


Fixed submission:
#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
// const int INF = 1e8;
using namespace std;

struct RAQ {
  using T = long long;
  T operator()(const T &a, const T &b) { return a + b; };
  static constexpr T identity() { return 0; }
};

template <class Monoid> class rangeAddQuery {
private:
  using T = typename Monoid::T;
  Monoid op;
  const int n;
  vector<T> dat, lazy;
  T query(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return op.identity();
    else if (a <= l && r <= b)
      return dat[k] * (r - l) + lazy[k];
    else {
      T res = (min(b, r) - max(a, l)) * dat[k];
      res += query(a, b, k * 2, l, (l + r) / 2);
      res += query(a, b, k * 2 + 1, (l + r) / 2, r);
      return res;
    }
  }
  void add(int a, int b, int k, int l, int r, T x) {
    if (a <= l && r <= b) {
      dat[k] += x;
    } else if (l < b && a < r) {
      lazy[k] += (min(b, r) - max(a, l)) * x;
      add(a, b, k * 2, l, (l + r) / 2, x);
      add(a, b, k * 2 + 1, (l + r) / 2, r, x);
    }
  }
  int power(int n) {
    int res = 1;
    while (n >= res)
      res *= 2;
    return res;
  }

public:
  rangeAddQuery(int n)
      : n(power(n)), dat(4 * n, op.identity()), lazy(4 * n, op.identity()) {}
  rangeAddQuery(const vector<T> &v)
      : n(v.size()), dat(4 * n), lazy(4 * n, op.identity()) {
    copy(begin(v), end(v), begin(dat) + n);
    for (int i = n - 1; i > 0; i--)
      dat[i] = op(dat[2 * i], dat[2 * i + 1]);
  }
  T query(int a, int b) { return query(a, b, 1, 0, n); }
  void add(int s, int t, T x) { add(s, t, 1, 0, n, x); }
  int get(int a) { return query(a, a + 1); };
  void out() {
    rep(i, n * 2) { cout << dat[i + 1] << ' '; }
    cout << endl;
  }
};

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

  rangeAddQuery<RAQ> seg(n);
  rep(i, q) {
    int com;
    cin >> com;
    if (not com) {
      int s, t, x;
      cin >> s >> t >> x;
      // cout << s << ' ' << t << endl;
      seg.add(s - 1, t, x);
    } else {
      int s, t;
      cin >> s >> t;
      assert(seg.query(s - 1, t) >= 0);
      cout << seg.query(s - 1, t) << endl;
    }
    // seg.out();
  }
}