Problem p00998 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

#define FOR(i, a, b) for (int i = a; i < b; i++)
#define REP(i, b) FOR(i, 0, b)
#define MP make_pair

using namespace std;

struct Node {
  Node *l, *r;
  int d, s, mn;
};

using NP = Node *;

const int poolSize = 1000000;
Node buf[poolSize];
stack<NP> pool;
void InitPool() {
  REP(i, poolSize)
  pool.push(buf + i);
}

int Depth(NP x) { return x ? x->d : 0; }

int Size(NP x) { return x ? x->s : 0; }

const int inf = 1145141919;

int Mini(NP x) { return x ? x->mn : inf; }

void delNode(NP x) { pool.push(x); }

NP newNode(NP l, NP r, int v = inf) {
  NP x = pool.top();
  pool.pop();
  *x = Node{l, r, max(Depth(l), Depth(r)) + 1, Size(l) + Size(r),
            min({v, Mini(l), Mini(r)})};
  return x;
}

Node Merge1(NP a, NP b, NP c) {
  if (abs(max(Depth(a), Depth(b)) + 1 - Depth(c)) <= 1)
    return Node{newNode(a, b), c};
  else if (abs(max(Depth(b), Depth(c)) + 1 - Depth(a)) <= 1)
    return Node{a, newNode(b, c)};
  Node ret = Node{newNode(a, b->l), newNode(b->r, c)};
  delNode(b);
  return ret;
}

Node Merge2(NP a, NP b) {
  if (Depth(a) == Depth(b))
    return Node{a, b};
  else if (Depth(a) > Depth(b)) {
    Node m = Merge2(a->r, b);
    Node ret = Merge1(a->l, m.l, m.r);
    delNode(a);
    return ret;
  } else {
    Node m = Merge2(a, b->l);
    Node ret = Merge1(m.l, m.r, b->r);
    delNode(b);
    return ret;
  }
}

NP Merge(NP a, NP b) {
  if (!a)
    return b;
  if (!b)
    return a;
  Node m = Merge2(a, b);
  return newNode(m.l, m.r);
}

Node Split(NP x, int k) {
  if (k <= 0)
    return Node{NULL, x};
  if (Size(x) <= k)
    return Node{x, NULL};
  if (k <= Size(x->l)) {
    Node s = Split(x->l, k);
    Node ret = Node{s.l, Merge(s.r, x->r)};
    delNode(x);
    return ret;
  } else {
    Node s = Split(x->r, k - Size(x->l));
    Node ret = Node{Merge(x->l, s.l), s.r};
    delNode(x);
    return ret;
  }
}

void Update(NP x, int k, int v) {
  if (Size(x) == 1) {
    x->mn = v;
    return;
  }
  if (k < Size(x->l))
    Update(x->l, k, v);
  else
    Update(x->r, k - Size(x->l), v);
  x->mn = min(Mini(x->l), Mini(x->r));
}

int read() {
  int i;
  scanf("%d", &i);
  return i;
}

NP t[100000];

int main() {
  InitPool();
  int n = read(), q = read();
  REP(i, n) {
    t[i] = newNode(NULL, NULL, read());
    t[i]->s = 1;
  }
  while (n > 1) {
    int k = n / 2;
    REP(i, k)
    t[i] = Merge(t[i * 2], t[i * 2 + 1]);
    if (k * 2 < n)
      t[k] = t[k * 2];
    n = (n + 1) / 2;
  }
  NP root = t[0];
  REP(_, q) {
    int x = read(), y = read(), z = read();
    if (x == 0) {
      Node s1 = Split(root, y);
      Node s2 = Split(s1.r, z + 1 - y - 1);
      Node s3 = Split(s2.r, 1);
      root = Merge(Merge(s1.l, s3.l), Merge(s2.l, s3.r));
    } else if (x == 1) {
      Node s1 = Split(root, y);
      Node s2 = Split(s1.r, z + 1 - y);
      printf("%d\n", Mini(s2.l));
      root = Merge(s1.l, Merge(s2.l, s2.r));
    } else if (x == 2) {
      Update(root, y, z);
    }
  }
}

Fixed submission:
#include <bits/stdc++.h>

#define FOR(i, a, b) for (int i = a; i < b; i++)
#define REP(i, b) FOR(i, 0, b)
#define MP make_pair

using namespace std;

struct Node {
  Node *l, *r;
  int d, s, mn;
};

using NP = Node *;

const int poolSize = 1000000;
Node buf[poolSize];
stack<NP> pool;
void InitPool() {
  REP(i, poolSize)
  pool.push(buf + i);
}

int Depth(NP x) { return x ? x->d : 0; }

int Size(NP x) { return x ? x->s : 0; }

const int inf = 1145141919;

int Mini(NP x) { return x ? x->mn : inf; }

void delNode(NP x) { pool.push(x); }

NP newNode(NP l, NP r, int v = inf) {
  NP x = pool.top();
  pool.pop();
  *x = Node{l, r, max(Depth(l), Depth(r)) + 1, Size(l) + Size(r),
            min({v, Mini(l), Mini(r)})};
  return x;
}

Node Merge1(NP a, NP b, NP c) {
  if (abs(max(Depth(a), Depth(b)) + 1 - Depth(c)) <= 1)
    return Node{newNode(a, b), c};
  else if (abs(max(Depth(b), Depth(c)) + 1 - Depth(a)) <= 1)
    return Node{a, newNode(b, c)};
  Node ret = Node{newNode(a, b->l), newNode(b->r, c)};
  delNode(b);
  return ret;
}

Node Merge2(NP a, NP b) {
  if (Depth(a) == Depth(b))
    return Node{a, b};
  else if (Depth(a) > Depth(b)) {
    Node m = Merge2(a->r, b);
    Node ret = Merge1(a->l, m.l, m.r);
    delNode(a);
    return ret;
  } else {
    Node m = Merge2(a, b->l);
    Node ret = Merge1(m.l, m.r, b->r);
    delNode(b);
    return ret;
  }
}

NP Merge(NP a, NP b) {
  if (!a)
    return b;
  if (!b)
    return a;
  Node m = Merge2(a, b);
  return newNode(m.l, m.r);
}

Node Split(NP x, int k) {
  if (k <= 0)
    return Node{NULL, x};
  if (Size(x) <= k)
    return Node{x, NULL};
  if (k <= Size(x->l)) {
    Node s = Split(x->l, k);
    Node ret = Node{s.l, Merge(s.r, x->r)};
    delNode(x);
    return ret;
  } else {
    Node s = Split(x->r, k - Size(x->l));
    Node ret = Node{Merge(x->l, s.l), s.r};
    delNode(x);
    return ret;
  }
}

void Update(NP x, int k, int v) {
  if (Size(x) == 1) {
    x->mn = v;
    return;
  }
  if (k < Size(x->l))
    Update(x->l, k, v);
  else
    Update(x->r, k - Size(x->l), v);
  x->mn = min(Mini(x->l), Mini(x->r));
}

int read() {
  int i;
  scanf("%d", &i);
  return i;
}

NP t[200000];

int main() {
  InitPool();
  int n = read(), q = read();
  REP(i, n) {
    t[i] = newNode(NULL, NULL, read());
    t[i]->s = 1;
  }
  while (n > 1) {
    int k = n / 2;
    REP(i, k)
    t[i] = Merge(t[i * 2], t[i * 2 + 1]);
    if (k * 2 < n)
      t[k] = t[k * 2];
    n = (n + 1) / 2;
  }
  NP root = t[0];
  REP(_, q) {
    int x = read(), y = read(), z = read();
    if (x == 0) {
      Node s1 = Split(root, y);
      Node s2 = Split(s1.r, z + 1 - y - 1);
      Node s3 = Split(s2.r, 1);
      root = Merge(Merge(s1.l, s3.l), Merge(s2.l, s3.r));
    } else if (x == 1) {
      Node s1 = Split(root, y);
      Node s2 = Split(s1.r, z + 1 - y);
      printf("%d\n", Mini(s2.l));
      root = Merge(s1.l, Merge(s2.l, s2.r));
    } else if (x == 2) {
      Update(root, y, z);
    }
  }
}