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

#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
#define INF (1 << 30)

struct Spray {
  Spray(int v) {
    val = v;
    minimum = v;
    size = 1;
    l = r = p = 0;
  }
  int val, minimum, size;
  Spray *l, *r, *p;

  int state() {
    if (p == 0)
      return 0;
    if (p->l == this)
      return -1;
    if (p->r == this)
      return 1;
  }

  Spray *update() {
    size = (l ? l->size : 0) + (r ? r->size : 0) + 1;
    minimum = min(val, min((l ? l->minimum : INF), (r ? r->minimum : INF)));
    return this;
  }

  void rotate() {
    Spray *par = p, *mid;
    if (par->l == this) {
      mid = r;
      r = par;
      par->l = mid;
    }
    if (par->r == this) {
      mid = l;
      l = par;
      par->r = mid;
    }
    if (mid)
      mid->p = par;
    p = par->p;
    par->p = this;
    if (p && p->l == par)
      p->l = this;
    if (p && p->r == par)
      p->r = this;
    par->update();
    update();
  }

  void spray() {
    while (state()) {
      int st = state() * p->state();
      if (st == -1)
        rotate();
      if (st == 1)
        p->rotate();
      rotate();
    }
  }
};

typedef pair<Spray *, Spray *> SprayP;
typedef SprayP P;

Spray *node(Spray *r, int pos) {
  int lsize = (r->l) ? r->l->size : 0;
  int rsize = (r->r) ? r->r->size : 0;
  if (lsize == pos - 1)
    return r;
  if (lsize > pos - 1)
    return node(r->l, pos);
  if (lsize < pos - 1)
    return node(r->r, pos - lsize - 1);
}

SprayP split(Spray *r, int pos) {
  if (pos == 0)
    return P(0, r);
  if (r->size == pos)
    return P(r, 0);
  r = node(r, pos);
  r->spray();
  Spray *right = r->r;
  r->r = 0;
  right->p = 0;
  return P(r->update(), right->update());
}

Spray *merge(Spray *a, Spray *b) {
  if (a == 0)
    return b;
  if (b == 0)
    return a;
  a = node(a, a->size);
  a->spray();
  b->spray();
  a->r = b;
  b->p = a;
  a->update();
  return a->update();
}

SprayP delt(Spray *r, int pos) {
  SprayP tmp1 = split(r, pos);
  SprayP tmp2 = split(tmp1.second, 1);
  return P(merge(tmp1.first, tmp2.second), tmp2.first);
}

Spray *insert(Spray *r, Spray *it, int pos) {
  SprayP tmp = split(r, pos);
  return merge(merge(tmp.first, it), tmp.second);
}

Spray *shift(Spray *r, int left, int right) {
  SprayP tmp = delt(r, right);
  return insert(tmp.first, tmp.second, left);
}

Spray *setnum(Spray *r, int pos, int val) {
  r = node(r, pos + 1);
  r->spray();
  r->val = val;
  return r->update();
}

Spray *comb(Spray *r, Spray *l) {
  l->l = r;
  if (r)
    r->p = l;
  return l->update();
}

int main() {
  int n, q, a, x, y, z;
  cin >> n >> q;
  Spray *r = 0;
  for (int i = 0; i < n; i++) {
    cin >> a;
    r = comb(r, new Spray(a));
  }
  for (int i = 0; i < q; i++) {
    cin >> x >> y >> z;
    if (x == 0) {
      r = shift(r, y, z);
    }
    if (x == 1) {
      SprayP tmp1 = split(r, z + 1);
      SprayP tmp2 = split(tmp1.first, y);
      cout << tmp2.second->minimum << endl;
      tmp1.first = merge(tmp2.first, tmp2.second);
      r = merge(tmp1.first, tmp1.second);
    }
    if (x == 2) {
      r = setnum(r, y, z);
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
struct Tree {
  Tree(int v) {
    size = 1;
    min = val = v;
    l = r = 0;
    index = 0;
  }
  Tree(){};
  int val, size, min, index;
  Tree *l, *r;
};

#define INF (1 << 30)
typedef pair<Tree *, Tree *> PTree;
Tree *root;

int size(Tree *a) { return a ? a->size : 0; }

int minimum(Tree *a) { return a ? a->min : INF; }

Tree *update(Tree *a) {
  if (a == 0)
    return 0;
  a->size = size(a->r) + size(a->l) + 1;
  a->min = min(a->val, min(minimum(a->r), minimum(a->l)));
  a->index = size(a->l);
  return a;
}

Tree *merge(Tree *a, Tree *b) {
  int p = size(a), q = size(b);
  if (p == 0)
    return b;
  if (q == 0)
    return a;
  if (rand() % (p + q) < p) {
    Tree *tmp = merge(a->r, b);
    a->r = tmp;
    return update(a);
  } else {
    Tree *tmp = merge(a, b->l);
    b->l = tmp;
    return update(b);
  }
}

PTree split(Tree *a, int pos) {
  if (pos == 0)
    return PTree(0, a);
  if (size(a) == pos)
    return PTree(a, 0);
  if (size(a->l) < pos) {
    PTree tmp = split(a->r, pos - 1 - size(a->l));
    a->r = tmp.first;
    tmp.first = update(a);
    return tmp;
  } else {
    PTree tmp = split(a->l, pos);
    a->l = tmp.second;
    tmp.second = update(a);
    return tmp;
  }
}

Tree *insert(Tree *a, int pos, int val) {
  PTree tmp = split(a, pos);
  tmp.first = merge(tmp.first, new Tree(val));
  return merge(tmp.first, tmp.second);
}

Tree *erase(Tree *a, int pos) {
  PTree tmp = split(a, pos);
  return merge(tmp.first, split(tmp.second, 1).second);
}

int minval(Tree *a, int left, int right) {
  PTree tmp = split(a, right);
  PTree tmpp = split(tmp.first, left);
  int res = minimum(tmpp.second);
  tmp.first = merge(tmpp.first, tmpp.second);
  a = merge(tmp.first, tmp.second);
  return res;
}

Tree *changeval(Tree *a, int pos, int val) {
  if (a->index == pos) {
    a->val = val;
  }
  if (a->index < pos) {
    changeval(a->r, pos - size(a->l) - 1, val);
  }
  if (a->index > pos) {
    changeval(a->l, pos, val);
  }
  return update(a);
}

int value(Tree *a, int pos) {
  if (a->index == pos) {
    return a->val;
  }
  if (a->index < pos) {
    return value(a->r, pos - size(a->l) - 1);
  }
  if (a->index > pos) {
    return value(a->l, pos);
  }
}

int main() {
  int n, q, num, x, y, z;
  cin >> n >> q;
  cin >> num;
  root = new Tree(num);
  for (int i = 1; i < n; i++) {
    cin >> num;
    root = merge(root, new Tree(num));
  }
  for (int i = 0; i < q; i++) {
    cin >> x >> y >> z;
    if (x == 0) {
      int num = value(root, z);
      root = erase(root, z);
      root = insert(root, y, num);
    }
    if (x == 1) {
      cout << minval(root, y, z + 1) << endl;
    }
    if (x == 2) {
      root = changeval(root, y, z);
    }
  }
  return 0;
}