Problem p02353 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define int long long
using namespace std;

/*Starry Sky Tree*/
/*Range Add Min(Max) Query*/
/*区間加算、区間Min,区間Max*/

class RSUQ {
public:
  // 遅延用の型
  struct T {
    int type; // 0 - empty   , 1 - update
    int value;
    T() : type(0), value(0) {}
    T(int type, int value) : type(type), value(value) {}
  };

  // マージ可能な主データ型
  struct D {
    int value;
    D() : value(0) {} /*適切な値にする!!!!!!*/
    D(int value) : value(value) {}
    bool operator<(D a) const { return value < a.value; } // merge用
  };

  int n;
  vector<D> dat;
  vector<T> td;
  D returnD = D(0); // 範囲外の時に返す値。

  RSUQ() { n = -1; }
  RSUQ(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    td.resize(2 * n - 1, T());
    dat.resize(2 * n - 1, D());
  }

  D merge(D a, D b) { return a.value + b.value; }

  void delay(int k, int len) {
    if (td[k].type == 0)
      return;
    int v = td[k].value;
    td[k].type = 0;
    td[k].value = 0;

    len /= 2;
    int l = k * 2 + 1, r = k * 2 + 2;
    dat[l].value = v * len;
    td[l].type = 1;
    td[l].value = v;
    dat[r].value = v * len;
    td[r].type = 1;
    td[r].value = v;
  }

  D write(int k, int x, int len) {
    dat[k].value = x * len;
    td[k].type = 1;
    td[k].value = x;
    return dat[k];
  }

  //[a,b)の値をx変更　query(a,b,x)
  D update(int a, int b, int x, bool flg = true, int k = 0, int l = 0,
           int r = -1) {
    if (r == -1)
      r = n, assert(a <= n && b <= n);
    if (r <= a || b <= l)
      return flg ? dat[k] : returnD;
    if (a <= l && r <= b)
      return flg ? write(k, x, r - l) : dat[k];

    delay(k, r - l);
    D vl = update(a, b, x, flg, k * 2 + 1, l, (l + r) / 2);
    D vr = update(a, b, x, flg, k * 2 + 2, (l + r) / 2, r);
    if (flg)
      dat[k] = merge(vl, vr);
    return merge(vl, vr);
  }

  //[a,b)の合計値を得る　find(a,b);
  int find(int a, int b) {
    D res = update(a, b, 0, false);
    return res.value;
  }
};

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

  RSUQ rsuq(n);

  while (q--) {
    int cmd;
    cin >> cmd;
    if (cmd == 0) {
      int s, t, x;
      cin >> s >> t >> x;
      rsuq.update(s, t + 1, x);
    }
    if (cmd == 1) {
      int s, t;
      cin >> s >> t;
      assert(s != t);
      cout << rsuq.find(s, t + 1) << endl;
    }
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define int long long
using namespace std;

/*Starry Sky Tree*/
/*Range Add Min(Max) Query*/
/*区間加算、区間Min,区間Max*/

class RSUQ {
public:
  // 遅延用の型
  struct T {
    int type; // 0 - empty   , 1 - update
    int value;
    T() : type(0), value(0) {}
    T(int type, int value) : type(type), value(value) {}
  };

  // マージ可能な主データ型
  struct D {
    int value;
    D() : value(0) {} /*適切な値にする!!!!!!*/
    D(int value) : value(value) {}
    bool operator<(D a) const { return value < a.value; } // merge用
  };

  int n;
  vector<D> dat;
  vector<T> td;
  D returnD = D(0); // 範囲外の時に返す値。

  RSUQ() { n = -1; }
  RSUQ(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    td.resize(2 * n - 1, T());
    dat.resize(2 * n - 1, D());
  }

  D merge(D a, D b) { return a.value + b.value; }

  void delay(int k, int len) {
    if (td[k].type == 0)
      return;
    int v = td[k].value;
    td[k].type = 0;
    td[k].value = 0;

    len /= 2;
    int l = k * 2 + 1, r = k * 2 + 2;
    dat[l].value = v * len;
    td[l].type = 1;
    td[l].value = v;
    dat[r].value = v * len;
    td[r].type = 1;
    td[r].value = v;
  }

  D write(int k, int x, int len) {
    dat[k].value = x * len;
    td[k].type = 1;
    td[k].value = x;
    return dat[k];
  }

  //[a,b)の値をx変更　query(a,b,x)
  D update(int a, int b, int x, bool flg = true, int k = 0, int l = 0,
           int r = -1) {
    if (r == -1)
      r = n, assert(a <= n && b <= n);
    if (r <= a || b <= l)
      return flg ? dat[k] : returnD;
    if (a <= l && r <= b)
      return flg ? write(k, x, r - l) : dat[k];

    delay(k, r - l);
    D vl = update(a, b, x, flg, k * 2 + 1, l, (l + r) / 2);
    D vr = update(a, b, x, flg, k * 2 + 2, (l + r) / 2, r);
    if (flg)
      dat[k] = merge(vl, vr);
    return merge(vl, vr);
  }

  //[a,b)の合計値を得る　find(a,b);
  int find(int a, int b) {
    D res = update(a, b, 0, false);
    return res.value;
  }
};

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

  RSUQ rsuq(n);

  while (q--) {
    int cmd;
    cin >> cmd;
    if (cmd == 0) {
      int s, t, x;
      cin >> s >> t >> x;
      rsuq.update(s, t + 1, x);
    }
    if (cmd == 1) {
      int s, t;
      cin >> s >> t;
      cout << rsuq.find(s, t + 1) << endl;
    }
  }

  return 0;
}