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

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <tuple>
#include <utility>
#include <vector>
#define loop(i, a, b) for (int i = (a); i < int(b); i++)
#define rep(i, n) loop(i, 0, n)

using namespace std;

int const inf = 1e9;
#define np (Node *)nullptr

unsigned int xor128() {
  static unsigned int x = 123456789, y = 362436069, z = 521288629, w = time(0);
  unsigned long t = x ^ (x << 11);
  x = y;
  y = z;
  z = w;
  return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}
unsigned int xor128r(int n) { return xor128() % n; }
double xor128d() { return xor128() * 0.00000000023283064365386962890625; }

struct Node {
  int val;
  Node *ch[2];
  int pri, cnt, sum_;
  int min_;
  Node(int v, int p) : val(v), pri(p), cnt(1), sum_(v), min_(v) {
    ch[0] = ch[1] = np;
  }
  // ~Node(){
  //     if(ch[0]) delete ch[0];
  //     if(ch[1]) delete ch[1];
  // }
  void *operator new(size_t sz) {
    static int pos = 0;
    static char mem[400020 * sizeof(Node)];
    Node *res = (Node *)(mem + pos);
    pos += sizeof(Node);
    return res;
  }

  static int count(Node *t) { return t == np ? 0 : t->cnt; }
  static int sum(Node *t) { return t == np ? 0 : t->sum_; }
  static int min(Node *t) { return t == np ? inf : t->min_; }

  void show(int ofs = 0) {
    if (ch[0])
      ch[0]->show(ofs + 1);
    rep(i, ofs * 2) putchar(' ');
    printf("v:%d m:%d (%p)\\n", val, min_, this);
    if (ch[1])
      ch[1]->show(ofs + 1);
  }

  void update() {
    cnt = count(ch[0]) + count(ch[1]) + 1;
    sum_ = sum(ch[0]) + sum(ch[1]) + val;
    min_ = std::min({min(ch[0]), min(ch[1]), val});
  }

  Node *merge(Node *r) {
    if (this == np || r == np)
      return this == np ? r : this;
    if (pri > r->pri) {
      ch[1] = ch[1]->merge(r);
      update();
      return this;
    } else {
      r->ch[0] = merge(r->ch[0]);
      r->update();
      return r;
    }
  }

  pair<Node *, Node *> split(int k) {
    int lc = count(ch[0]);
    if (k <= lc) {
      auto s = ch[0] ? ch[0]->split(k) : make_pair(np, np);
      ch[0] = s.second;
      update();
      return make_pair(s.first, this);
    } else {
      auto s = ch[1] ? ch[1]->split(k - lc - 1) : make_pair(np, np);
      ch[1] = s.first;
      update();
      return make_pair(this, s.second);
    }
  }

  Node *erase(int k) {
    Node *l, *m, *r;
    tie(l, m) = split(k);
    tie(m, r) = m->split(1);
    // delete m;
    return l->merge(r);
  }

  Node *at(int k) {
    int lc = count(ch[0]);
    if (k < lc)
      return ch[0]->at(k);
    else if (k == lc)
      return this;
    else
      return ch[1]->at(k - lc - 1);
  }

  void set(int k, int x) {
    int lc = count(ch[0]);
    if (k < lc)
      ch[0]->set(k, x);
    else if (k == lc)
      val = x;
    else if (k > lc)
      ch[1]->set(k - lc - 1, x);
    update();
  }

  Node *insert(int k, int v) {
    Node *l, *m = new Node(v, xor128()), *r;
    tie(l, r) = split(k);
    return l->merge(m)->merge(r); // merge(merge(l,m),r);
  }

  int min(int l, int r) {
    if (r - l <= 0)
      return inf;
    if (r - l == count(this))
      return min(this);
    int lc = count(ch[0]);
    if (l == lc && r - lc == 1)
      return val;
    int res = inf;
    if (l < lc)
      res = std::min(res, ch[0]->min(l, std::min(lc, r)));
    if (l <= lc && lc < r)
      res = std::min(res, min(lc, lc + 1));
    if (lc + 1 < r)
      res = std::min(res, ch[1]->min(max(0, l - lc - 1), r - lc - 1));
    return res;
  }
  static int min(Node *t, int l, int r) {
    if (r - l <= 0)
      return inf;
    if (r - l == count(t))
      return min(t);
    int lc = count(t->ch[0]);
    if (l == lc && r - lc == 1)
      return t->val;
    int res = inf;
    if (l < lc)
      res = std::min(res, min(t->ch[0], l, std::min(lc, r)));
    if (l <= lc && lc < r)
      res = std::min(res, min(t, lc, lc + 1));
    if (lc + 1 < r)
      res = std::min(res, min(t->ch[1], max(0, l - lc - 1), r - lc - 1));
    return res;
  }
};

struct Treap {
  Node *root;
  int size;
  Treap() : root(nullptr), size(0) {}
  void shift(int l, int r) {
    int tmp = root->at(r)->val;
    root = root->erase(r);
    root = root->insert(l, tmp);
  }
  void set(int k, int x) { root->set(k, x); }
  int rangemin(int l, int r) { return Node::min(root, l, r); }
  void push_back(int x) {
    if (size == 0)
      root = new Node(x, xor128()), size++;
    else
      root = root->insert(size++, x);
  }
};

int get() {
  int x;
  scanf("%d", &x);
  return x;
}

void put(int x) {
  // printf("ans : %d\\n",x);
  printf("%d\\n", x);
}

int main() {
#ifdef DEBUG
  freopen("in", "r", stdin);
#endif
  int n = get(), q = get();
  Treap t;
  rep(i, n) t.push_back(get());

  rep(i, q) {
    int op = get();
    if (false) {
    } else if (op == 0) {
      int l = get(), r = get();
      t.shift(l, r);
    } else if (op == 1) {
      int l = get(), r = get();
      r++;
      put(t.rangemin(l, r));
    } else if (op == 2) {
      int p = get(), v = get();
      t.set(p, v);
    }
  }
}

Error: -6
munmap_chunk(): invalid pointer


Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <tuple>
#include <utility>
#include <vector>
#define loop(i, a, b) for (int i = (a); i < int(b); i++)
#define rep(i, n) loop(i, 0, n)

using namespace std;

int const inf = 1e9;
#define np (Node *)nullptr

unsigned int xor128() {
  static unsigned int x = 123456789, y = 362436069, z = 521288629, w = time(0);
  unsigned long t = x ^ (x << 11);
  x = y;
  y = z;
  z = w;
  return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}
unsigned int xor128r(int n) { return xor128() % n; }
double xor128d() { return xor128() * 0.00000000023283064365386962890625; }

struct Node {
  int val;
  Node *ch[2];
  int pri, cnt, sum_;
  int min_;
  Node(int v, int p) : val(v), pri(p), cnt(1), sum_(v), min_(v) {
    ch[0] = ch[1] = np;
  }
  // ~Node(){
  //     if(ch[0]) delete ch[0];
  //     if(ch[1]) delete ch[1];
  // }
  void *operator new(size_t sz) {
    static int pos = 0;
    static char mem[400020 * sizeof(Node)];
    Node *res = (Node *)(mem + pos);
    pos += sizeof(Node);
    return res;
  }

  static int count(Node *t) { return t == np ? 0 : t->cnt; }
  static int sum(Node *t) { return t == np ? 0 : t->sum_; }
  static int min(Node *t) { return t == np ? inf : t->min_; }

  void show(int ofs = 0) {
    if (ch[0])
      ch[0]->show(ofs + 1);
    rep(i, ofs * 2) putchar(' ');
    printf("v:%d m:%d (%p)\\n", val, min_, this);
    if (ch[1])
      ch[1]->show(ofs + 1);
  }

  void update() {
    cnt = count(ch[0]) + count(ch[1]) + 1;
    sum_ = sum(ch[0]) + sum(ch[1]) + val;
    min_ = std::min({min(ch[0]), min(ch[1]), val});
  }

  Node *merge(Node *r) {
    if (this == np || r == np)
      return this == np ? r : this;
    if (pri > r->pri) {
      ch[1] = ch[1]->merge(r);
      update();
      return this;
    } else {
      r->ch[0] = merge(r->ch[0]);
      r->update();
      return r;
    }
  }

  pair<Node *, Node *> split(int k) {
    int lc = count(ch[0]);
    if (k <= lc) {
      auto s = ch[0] ? ch[0]->split(k) : make_pair(np, np);
      ch[0] = s.second;
      update();
      return make_pair(s.first, this);
    } else {
      auto s = ch[1] ? ch[1]->split(k - lc - 1) : make_pair(np, np);
      ch[1] = s.first;
      update();
      return make_pair(this, s.second);
    }
  }

  Node *erase(int k) {
    Node *l, *m, *r;
    tie(l, m) = split(k);
    tie(m, r) = m->split(1);
    delete m;
    return l->merge(r);
  }

  Node *at(int k) {
    int lc = count(ch[0]);
    if (k < lc)
      return ch[0]->at(k);
    else if (k == lc)
      return this;
    else
      return ch[1]->at(k - lc - 1);
  }

  void set(int k, int x) {
    int lc = count(ch[0]);
    if (k < lc)
      ch[0]->set(k, x);
    else if (k == lc)
      val = x;
    else if (k > lc)
      ch[1]->set(k - lc - 1, x);
    update();
  }

  Node *insert(int k, int v) {
    Node *l, *m = new Node(v, xor128()), *r;
    tie(l, r) = split(k);
    return l->merge(m)->merge(r); // merge(merge(l,m),r);
  }

  int min(int l, int r) {
    if (r - l <= 0)
      return inf;
    if (r - l == count(this))
      return min(this);
    int lc = count(ch[0]);
    if (l == lc && r - lc == 1)
      return val;
    int res = inf;
    if (l < lc)
      res = std::min(res, ch[0]->min(l, std::min(lc, r)));
    if (l <= lc && lc < r)
      res = std::min(res, min(lc, lc + 1));
    if (lc + 1 < r)
      res = std::min(res, ch[1]->min(max(0, l - lc - 1), r - lc - 1));
    return res;
  }
  static int min(Node *t, int l, int r) {
    if (r - l <= 0)
      return inf;
    if (r - l == count(t))
      return min(t);
    int lc = count(t->ch[0]);
    if (l == lc && r - lc == 1)
      return t->val;
    int res = inf;
    if (l < lc)
      res = std::min(res, min(t->ch[0], l, std::min(lc, r)));
    if (l <= lc && lc < r)
      res = std::min(res, min(t, lc, lc + 1));
    if (lc + 1 < r)
      res = std::min(res, min(t->ch[1], max(0, l - lc - 1), r - lc - 1));
    return res;
  }
};

struct Treap {
  Node *root;
  int size;
  Treap() : root(nullptr), size(0) {}
  void shift(int l, int r) {
    int tmp = root->at(r)->val;
    root = root->erase(r);
    root = root->insert(l, tmp);
  }
  void set(int k, int x) { root->set(k, x); }
  int rangemin(int l, int r) { return Node::min(root, l, r); }
  void push_back(int x) {
    if (size == 0)
      root = new Node(x, xor128()), size++;
    else
      root = root->insert(size++, x);
  }
};

int get() {
  int x;
  scanf("%d", &x);
  return x;
}

void put(int x) {
  // printf("ans : %d\\n",x);
  printf("%d\\n", x);
}

int main() {
#ifdef DEBUG
  freopen("in", "r", stdin);
#endif
  int n = get(), q = get();
  Treap t;
  rep(i, n) t.push_back(get());

  rep(i, q) {
    int op = get();
    if (false) {
    } else if (op == 0) {
      int l = get(), r = get();
      t.shift(l, r);
    } else if (op == 1) {
      int l = get(), r = get();
      r++;
      put(t.rangemin(l, r));
    } else if (op == 2) {
      int p = get(), v = get();
      t.set(p, v);
    }
  }
}