Problem p01057 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
typedef long long ll;

struct NTree {
  // syakyou simasita
  // demo TLE sisou...
  struct Node;
  typedef char D;
  typedef Node *NP;
  static Node last_d;
  static NP last;
  struct Node {
    NP l, r;
    int sz;
    D v;
    Node(D v) : l(last), r(last), sz(1), v(v) {}
    Node() : l(nullptr), r(nullptr), sz(0) {}

    NP update() {
      sz = 1 + l->sz + r->sz;
      return this;
    }

    void set(int a, D x) {
      if (a < l->sz) {
        l->set(a, x);
      } else if (a == l->sz) {
        v = x;
      } else {
        r->set(a - (l->sz + 1), x);
      }
    }
    void allget(D d[]) {
      if (!sz)
        return;
      l->allget(d);
      d[l->sz] = v;
      r->allget(d + l->sz + 1);
    }
  } *n;

  static uint xor128() {
    static uint x = 123456789, y = 362436039, z = 525188629, w = 88675123;
    uint t;
    t = (x ^ (x << 11));
    x = y;
    y = z;
    z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
  }

  static NP merge(NP l, NP r) {
    if (!l->sz)
      return r;
    if (!r->sz)
      return l;
    if ((int)(xor128() % (l->sz + r->sz)) < l->sz) {
      l->r = merge(l->r, r);
      return l->update();
    } else {
      r->l = merge(l, r->l);
      return r->update();
    }
  }

  static pair<NP, NP> split(NP x, int k) {
    if (!x->sz)
      return {last, last};
    if (k <= x->l->sz) {
      auto y = split(x->l, k);
      x->l = y.second;
      y.second = x->update();
      return y;
    } else {
      auto y = split(x->r, k - x->l->sz - 1);
      x->r = y.first;
      y.first = x->update();
      return y;
    }
  }

  static NP built(int sz, D d[]) {
    if (!sz)
      return last;
    int md = sz / 2;
    NP x = new Node(d[md]);
    x->l = built(md, d);
    x->r = built(sz - (md + 1), d + (md + 1));
    return x->update();
  }
  NTree() : n(last) {}
  NTree(NP n) : n(n) {}
  NTree(D d) : n(new Node(d)) {}
  NTree(int sz, D d[]) { n = built(sz, d); }
  void merge(NTree r) { n = merge(n, r.n); }

  NTree split(int k) {
    auto u = split(n, k);
    n = u.first;
    return NTree(u.second);
  }
  void set(int a, D x) { n->set(a, x); }
  void allget(D d[]) {
    n->allget(d);
    d[n->sz] = '\0';
  }
};
NTree::Node NTree::last_d = NTree::Node();
NTree::NP NTree::last = &last_d;

const int MN = 100100;
const int MS = 1000100;
NTree tr[MN];
char buf[MS];

void deb(NTree t) {
  t.allget(buf);
  printf("d %s\n", buf);
}
int main() {
  int n, q;
  scanf("%d %d", &n, &q);
  for (int i = 0; i < n; i++) {
    scanf(" %s", buf);
    tr[i] = NTree(strlen(buf), buf);
  }

  for (int i = 0; i < q; i++) {
    int ty;
    scanf("%d", &ty);
    //		printf("quey %d %d\n", i, ty);
    if (ty == 1) {
      int a, b, c, d;
      scanf("%d %d %d %d", &a, &b, &c, &d);
      a--;
      b--;
      c--;
      d--;
      //			printf("%d %d %d %d\n", a, b, c, d);
      //			deb(tr[a]);
      //			deb(tr[c]);
      auto t1 = tr[a].split(b);
      auto t2 = tr[c].split(d);
      //			deb(t1);
      //			deb(t2);
      tr[a].merge(t2);
      tr[c].merge(t1);
      //			deb(tr[a]);
      //			deb(tr[c]);
    } else {
      int a, b;
      char c;
      scanf("%d %d %c", &a, &b, &c);
      a--;
      b--;
      //			printf("type 2 %d %d %d\n", a, b, tr[a].n->sz);
      tr[a].set(b, c);
    }
    for (int i = 0; i < n; i++) {
      //			tr[i].allget(buf);
      //			printf("%s\n", buf);
    }
    //		printf("\n");
    //		printf("\n");
  }
  for (int i = 0; i < n; i++) {
    tr[i].allget(buf);
    printf("%s\n", buf);
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
typedef long long ll;

struct NTree {
  // syakyou simasita
  // demo TLE sisou...
  struct Node;
  typedef char D;
  typedef Node *NP;
  static Node last_d;
  static NP last;
  struct Node {
    NP l, r;
    int sz;
    D v;
    Node(D v) : l(last), r(last), sz(1), v(v) {}
    Node() : l(nullptr), r(nullptr), sz(0) {}

    NP update() {
      sz = 1 + l->sz + r->sz;
      return this;
    }

    void set(int a, D x) {
      if (a < l->sz) {
        l->set(a, x);
      } else if (a == l->sz) {
        v = x;
      } else {
        r->set(a - (l->sz + 1), x);
      }
    }
    void allget(D d[]) {
      if (!sz)
        return;
      l->allget(d);
      d[l->sz] = v;
      r->allget(d + l->sz + 1);
    }
  } *n;

  static uint xor128() {
    static uint x = 123456789, y = 362436039, z = 525188629, w = 88675123;
    uint t;
    t = (x ^ (x << 11));
    x = y;
    y = z;
    z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
  }

  static NP merge(NP l, NP r) {
    if (!l->sz)
      return r;
    if (!r->sz)
      return l;
    if ((int)(xor128() % (l->sz + r->sz)) < l->sz) {
      l->r = merge(l->r, r);
      return l->update();
    } else {
      r->l = merge(l, r->l);
      return r->update();
    }
  }

  static pair<NP, NP> split(NP x, int k) {
    if (!x->sz)
      return {last, last};
    if (k <= x->l->sz) {
      auto y = split(x->l, k);
      x->l = y.second;
      y.second = x->update();
      return y;
    } else {
      auto y = split(x->r, k - x->l->sz - 1);
      x->r = y.first;
      y.first = x->update();
      return y;
    }
  }

  static NP built(int sz, D d[]) {
    if (!sz)
      return last;
    int md = sz / 2;
    NP x = new Node(d[md]);
    x->l = built(md, d);
    x->r = built(sz - (md + 1), d + (md + 1));
    return x->update();
  }
  NTree() : n(last) {}
  NTree(NP n) : n(n) {}
  NTree(D d) : n(new Node(d)) {}
  NTree(int sz, D d[]) { n = built(sz, d); }
  void merge(NTree r) { n = merge(n, r.n); }

  NTree split(int k) {
    auto u = split(n, k);
    n = u.first;
    return NTree(u.second);
  }
  void set(int a, D x) { n->set(a, x); }
  void allget(D d[]) {
    n->allget(d);
    d[n->sz] = '\0';
  }
};
NTree::Node NTree::last_d = NTree::Node();
NTree::NP NTree::last = &last_d;

const int MN = 100100;
const int MS = 2000100;
NTree tr[MN];
char buf[MS];

void deb(NTree t) {
  t.allget(buf);
  printf("d %s\n", buf);
}
int main() {
  int n, q;
  scanf("%d %d", &n, &q);
  for (int i = 0; i < n; i++) {
    scanf(" %s", buf);
    tr[i] = NTree(strlen(buf), buf);
  }

  for (int i = 0; i < q; i++) {
    int ty;
    scanf("%d", &ty);
    //		printf("quey %d %d\n", i, ty);
    if (ty == 1) {
      int a, b, c, d;
      scanf("%d %d %d %d", &a, &b, &c, &d);
      a--;
      b--;
      c--;
      d--;
      //			printf("%d %d %d %d\n", a, b, c, d);
      //			deb(tr[a]);
      //			deb(tr[c]);
      auto t1 = tr[a].split(b);
      auto t2 = tr[c].split(d);
      //			deb(t1);
      //			deb(t2);
      tr[a].merge(t2);
      tr[c].merge(t1);
      //			deb(tr[a]);
      //			deb(tr[c]);
    } else {
      int a, b;
      char c;
      scanf("%d %d %c", &a, &b, &c);
      a--;
      b--;
      //			printf("type 2 %d %d %d\n", a, b, tr[a].n->sz);
      tr[a].set(b, c);
    }
    for (int i = 0; i < n; i++) {
      //			tr[i].allget(buf);
      //			printf("%s\n", buf);
    }
    //		printf("\n");
    //		printf("\n");
  }
  for (int i = 0; i < n; i++) {
    tr[i].allget(buf);
    printf("%s\n", buf);
  }
  return 0;
}