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

#include <algorithm>
#include <iostream>
using namespace std;

#define INF (1 << 30)

class Sequence { // AVLTree
  struct Node {
    int height;
    Node *left, *right;
    int size;
    int index, added;
    int val, minsub;

    Node(int k, int v)
        : height(1), index(k), added(0), left(0), right(0), size(1), val(v),
          minsub(v) {}
    ~Node() {
      if (left)
        delete left;
      if (right)
        delete right;
    }
    Node *rotate_right() {
      Node *s = left;
      int b = s->added, d = added;
      s->added += d;
      if (s->right)
        s->right->added += b;
      added += -b - d;
      left = s->right;
      s->right = this;
      return s;
    }
    Node *rotate_left() {
      Node *s = right;
      int b = s->added, d = added;
      s->added += d;
      if (s->left)
        s->left->added += b;
      added += -b - d;
      right = s->left;
      s->left = this;
      return s;
    }
    Node *insert(int k, int v) {
      if (!this)
        return new Node(k, v);
      k -= added;
      if (k < index) {
        left = left->insert(k, v);
      } else { // key < k
        right = right->insert(k, v);
      }
      return balance();
    }
    bool find(int k) {
      if (!this)
        return false;
      k -= added;
      return k == index ? true : k < index ? left->find(k) : right->find(k);
    }
    Node *erase(int k) {
      if (!this)
        return NULL;
      k -= added;
      if (k == index) {
        int a = added;
        Node *le = left, *ri = right;
        left = right = NULL;
        delete this;
        if (!le) {
          if (ri)
            ri->added += a;
          return ri;
        }
        if (!ri) {
          if (le)
            le->added += a;
          return le;
        }
        Node *t;
        le = le->erase_max(&t, a, a);
        t->left = le;
        t->right = ri;
        return t->balance();
      }
      if (k < index) {
        left = left->erase(k);
      } else if (index < k) {
        right = right->erase(k);
      }
      return balance();
    }
    int min(int a, int b, int l, int r, int s) const {
      if (!this || r < a || b < l)
        return INF;
      if (a <= l && r <= b)
        return minsub;
      s += added;
      int i = index + s;
      int res = a <= i && i <= b ? val : INF;
      res = std::min(res, left->min(a, b, l, i - 1, s));
      res = std::min(res, right->min(a, b, i + 1, r, s));
      return res;
    }
    void substitute(int k, int v) {
      k -= added;
      if (k == index) {
        val = v;
      }
      if (k < index) {
        left->substitute(k, v);
      } else if (index < k) {
        right->substitute(k, v);
      }
      updates();
    }

    void add_ge(int k, int v) {
      if (!this)
        return;
      k -= added;
      if (k <= index) {
        added += v;
        if (left) {
          left->added -= v;
          left->add_ge(k - v, v);
        }
      } else {
        right->add_ge(k, v);
      }
    }
    Node *balance() {
      int bf = (right ? right->height : 0) - (left ? left->height : 0);
      if (2 == bf) {
        Node *t = right;
        if ((t->right ? t->right->height : 0) <
            (t->left ? t->left->height : 0)) {
          right = t->rotate_right();
        }
        return rotate_left()->update();
      } else if (bf == -2) {
        Node *t = left;
        if ((t->right ? t->right->height : 0) >
            (t->left ? t->left->height : 0)) {
          left = t->rotate_left();
        }
        return rotate_right()->update();
      }
      updates();
      return this;
    }
    Node *update() {
      if (left)
        left->updates();
      if (right)
        right->updates();
      updates();
      return this;
    }
    void updates() {
      update_height();
      update_size();
      update_min();
    }
    void update_height() {
      if (!this)
        return;
      if (right) {
        if (left && right->height < left->height)
          height = left->height + 1;
        else
          height = right->height + 1;
      } else if (left)
        height = left->height + 1;
      else
        height = 1;
    }
    void update_size() {
      if (!this)
        return;
      size = 1 + (left ? left->size : 0) + (right ? right->size : 0);
    }
    void update_min() {
      if (!this)
        return;
      minsub = val;
      if (left)
        minsub = std::min(minsub, left->minsub);
      if (right)
        minsub = std::min(minsub, right->minsub);
    }
    Node *erase_max(Node **maxnode, int add, int s) {
      s += added;
      if (right) {
        right = right->erase_max(maxnode, add, s);
        return balance();
      } else {
        *maxnode = this;
        if (left)
          left->added += added;
        index = index + s - add;
        added = add;
        return left;
      }
    }
  } *root;

public:
  Sequence() : root(0) {}
  ~Sequence() {
    if (root)
      delete root;
  }
  void insert(int k, int v) {
    root->add_ge(k, 1);
    root = root->insert(k, v);
  }
  void erase(int k) {
    root = root->erase(k);
    root->add_ge(k, -1);
  }
  int min(int a, int b) const { return root->min(a, b, 0, root->size - 1, 0); }
  void substitute(int k, int v) { root->substitute(k, v); }
};

int main() {
  int n, q;
  Sequence seq;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    seq.insert(i, a);
  }
  for (int i = 0; i < q; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    if (x == 0) {
      int v = seq.min(z, z);
      seq.erase(z);
      seq.insert(y, v);
    } else if (x == 1) {
      cout << seq.min(y, z) << endl;
    } else {
      seq.substitute(y, z);
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
using namespace std;

#define INF (1 << 30)

class Sequence { // AVLTree
  struct Node {
    int height;
    Node *left, *right;
    int size;
    int index, added;
    int val, minsub;

    Node(int k, int v)
        : height(1), index(k), added(0), left(0), right(0), size(1), val(v),
          minsub(v) {}
    ~Node() {
      if (left)
        delete left;
      if (right)
        delete right;
    }
    Node *rotate_right() {
      Node *s = left;
      int b = s->added, d = added;
      s->added += d;
      if (s->right)
        s->right->added += b;
      added += -b - d;
      left = s->right;
      s->right = this;
      return s;
    }
    Node *rotate_left() {
      Node *s = right;
      int b = s->added, d = added;
      s->added += d;
      if (s->left)
        s->left->added += b;
      added += -b - d;
      right = s->left;
      s->left = this;
      return s;
    }
    Node *insert(int k, int v) {
      if (!this)
        return new Node(k, v);
      k -= added;
      if (k < index) {
        left = left->insert(k, v);
      } else { // key < k
        right = right->insert(k, v);
      }
      return balance();
    }
    bool find(int k) {
      if (!this)
        return false;
      k -= added;
      return k == index ? true : k < index ? left->find(k) : right->find(k);
    }
    Node *erase(int k) {
      if (!this)
        return NULL;
      k -= added;
      if (k == index) {
        int a = added;
        Node *le = left, *ri = right;
        left = right = NULL;
        delete this;
        if (!le) {
          if (ri)
            ri->added += a;
          return ri;
        }
        if (!ri) {
          if (le)
            le->added += a;
          return le;
        }
        Node *t;
        le = le->erase_max(&t, a, a);
        t->left = le;
        t->right = ri;
        return t->balance();
      }
      if (k < index) {
        left = left->erase(k);
      } else if (index < k) {
        right = right->erase(k);
      }
      return balance();
    }
    int min(int a, int b, int l, int r, int s) const {
      if (r < a || b < l)
        return INF;
      if (a <= l && r <= b)
        return minsub;
      s += added;
      int i = index + s;
      int res = a <= i && i <= b ? val : INF;
      res = std::min(res, left->min(a, b, l, i - 1, s));
      res = std::min(res, right->min(a, b, i + 1, r, s));
      return res;
    }

    void add_ge(int k, int v) {
      if (!this)
        return;
      k -= added;
      if (k <= index) {
        added += v;
        if (left) {
          left->added -= v;
          left->add_ge(k - v, v);
        }
      } else {
        right->add_ge(k, v);
      }
    }
    Node *balance() {
      int bf = (right ? right->height : 0) - (left ? left->height : 0);
      if (2 == bf) {
        Node *t = right;
        if ((t->right ? t->right->height : 0) <
            (t->left ? t->left->height : 0)) {
          right = t->rotate_right();
        }
        return rotate_left()->update();
      } else if (bf == -2) {
        Node *t = left;
        if ((t->right ? t->right->height : 0) >
            (t->left ? t->left->height : 0)) {
          left = t->rotate_left();
        }
        return rotate_right()->update();
      }
      updates();
      return this;
    }
    Node *update() {
      if (left)
        left->updates();
      if (right)
        right->updates();
      updates();
      return this;
    }
    void updates() {
      update_height();
      update_size();
      update_min();
    }
    void update_height() {
      if (!this)
        return;
      if (right) {
        if (left && right->height < left->height)
          height = left->height + 1;
        else
          height = right->height + 1;
      } else if (left)
        height = left->height + 1;
      else
        height = 1;
    }
    void update_size() {
      if (!this)
        return;
      size = 1 + (left ? left->size : 0) + (right ? right->size : 0);
    }
    void update_min() {
      if (!this)
        return;
      minsub = val;
      if (left)
        minsub = std::min(minsub, left->minsub);
      if (right)
        minsub = std::min(minsub, right->minsub);
    }
    Node *erase_max(Node **maxnode, int add, int s) {
      s += added;
      if (right) {
        right = right->erase_max(maxnode, add, s);
        return balance();
      } else {
        *maxnode = this;
        index = index + s - add;
        added = add;
        if (left)
          left->index += added;
        return left;
      }
    }
  } *root;

public:
  Sequence() : root(0) {}
  ~Sequence() {
    if (root)
      delete root;
  }
  void insert(int k, int v) {
    root->add_ge(k, 1);
    root = root->insert(k, v);
  }
  void erase(int k) {
    root = root->erase(k);
    root->add_ge(k, -1);
  }
  int min(int a, int b) const { return root->min(a, b, 0, root->size - 1, 0); }
  void substitute(int k, int v) {
    root = root->erase(k);
    root = root->insert(k, v);
  }
};

int main() {
  int n, q;
  Sequence seq;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    seq.insert(i, a);
  }
  for (int i = 0; i < q; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    if (x == 0) {
      int v = seq.min(z, z);
      seq.erase(z);
      seq.insert(y, v);
    } else if (x == 1) {
      cout << seq.min(y, z) << endl;
    } else {
      seq.substitute(y, z);
    }
  }
  return 0;
}