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

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using ll = long long;
using R = long double;
const R EPS = 1e-9; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max<R>(x, 0.0)); }

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Treap based on merge and split
// each operation
// set parameter
const int inf = 1 << 29;
const int nmax = 1000010;

mt19937 mt;
uniform_real_distribution<double> rnd(0.0, 1.0);

struct Node {
  int val, cnt, min, add, rev;
  Node *lch = nullptr, *rch = nullptr;
  double pri;
  Node() {}
  Node(int v) : val(v), cnt(1), min(v), add(0), rev(0), pri(rnd(mt)) {}
};

// memory pool
int total = 0;
Node pool[nmax];

Node *create(int v) {
  pool[total] = Node(v);
  return &(pool[total++]);
}

// helper function
int val(Node *x) {
  assert(x != nullptr);
  return x->val + x->add;
}
int cnt(Node *x) { return (x == nullptr) ? 0 : x->cnt; }
int min(Node *x) { return (x == nullptr) ? inf : x->min + x->add; }

Node *update(Node *x) {
  if (x == nullptr)
    return x;

  x->cnt = 1 + cnt(x->lch) + cnt(x->rch);
  x->min = min({val(x), min(x->lch), min(x->rch)});

  if (x->add) {
    x->val += x->add;
    if (x->lch != nullptr)
      x->lch->add += x->add;
    if (x->rch != nullptr)
      x->rch->add += x->add;
    x->add = 0;
  }

  if (x->rev) {
    swap(x->lch, x->rch);
    if (x->lch != nullptr)
      x->lch->rev ^= true;
    if (x->rch != nullptr)
      x->rch->rev ^= true;
    x->rev = false;
  }

  return x;
}

Node *merge(Node *l, Node *r) {
  l = update(l), r = update(r);
  if (l == nullptr)
    return r;
  if (r == nullptr)
    return l;

  if (l->pri > r->pri) {
    l->rch = merge(l->rch, r);
    return update(l);
  } else {
    r->lch = merge(l, r->lch);
    return update(r);
  }
}

tuple<Node *, Node *> split(Node *x, int k) { //[0,k) [k,n)
  x = update(x);
  if (x == nullptr)
    return make_tuple(nullptr, nullptr);

  Node *l, *r;
  if (k <= cnt(x->lch)) {
    tie(l, r) = split(x->lch, k);
    x->lch = r;
    return make_tuple(update(l), update(x));
  } else {
    tie(l, r) = split(x->rch, k - cnt(x->lch) - 1);
    x->rch = l;
    return make_tuple(update(x), update(r));
  }
}

Node *range_merge(Node *left, Node *tar, Node *right) {
  return merge(left, merge(tar, right));
}

tuple<Node *, Node *, Node *> range_split(Node *t, int l, int r) {
  Node *left, *tar, *right;
  tie(tar, right) = split(t, r);
  tie(left, tar) = split(tar, l);
  return make_tuple(left, tar, right);
}

void insert(Node *&t, int k, int v) {
  Node *left, *right, *tar = create(v);
  tie(left, right) = split(t, k);
  t = range_merge(left, tar, right);
}

void erase(Node *&t, int k) {
  Node *left, *tar, *right;
  tie(left, tar, right) = range_split(t, k, k + 1);
  t = merge(left, right);
}

void shift(Node *&t, int l, int r) {
  Node *left, *tar, *right;
  tie(left, tar, right) = range_split(t, l, r);
  Node *tar_l, *tar_r;
  tie(tar_l, tar_r) = split(tar, cnt(tar) - 1);
  tar = merge(tar_r, tar_l);
  t = range_merge(left, tar, right);
}

int min(Node *&t, int l, int r) {
  Node *left, *tar, *right;
  tie(left, tar, right) = range_split(t, l, r);
  int ret = tar->min;
  t = range_merge(left, tar, right);
  return ret;
}

void change(Node *&t, int p, int v) {
  erase(t, p);
  insert(t, p, v);
}

int main(void) {
  int n, q;
  cin >> n >> q;

  Node *t = nullptr;

  rep(i, n) {
    int in;
    cin >> in;
    t = merge(t, create(in));
  }

  rep(loop, q) {
    int type, a, b;
    cin >> type >> a >> b;
    if (type == 0)
      shift(t, a, b + 1);
    else if (type == 1)
      cout << min(t, a, b + 1) << endl;
    else
      change(t, a, b);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using ll = long long;
using R = long double;
const R EPS = 1e-9; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max<R>(x, 0.0)); }

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Treap based on merge and split
// each operation
// set parameter
const int inf = 1 << 29;
const int nmax = 1000010;

mt19937 mt;
uniform_real_distribution<double> rnd(0.0, 1.0);

struct Node {
  int val, cnt, min, add, rev;
  Node *lch = nullptr, *rch = nullptr;
  double pri;
  Node() {}
  Node(int v) : val(v), cnt(1), min(v), add(0), rev(0), pri(rnd(mt)) {}
};

// memory pool
int total = 0;
Node pool[nmax];

Node *create(int v) {
  pool[total] = Node(v);
  return &(pool[total++]);
}

// helper function
int val(Node *x) {
  assert(x != nullptr);
  return x->val + x->add;
}
int cnt(Node *x) { return (x == nullptr) ? 0 : x->cnt; }
int min(Node *x) { return (x == nullptr) ? inf : x->min + x->add; }

Node *update(Node *x) {
  if (x == nullptr)
    return x;

  x->cnt = 1 + cnt(x->lch) + cnt(x->rch);
  x->min = min({val(x), min(x->lch), min(x->rch)});

  if (x->add) {
    x->val += x->add;
    if (x->lch != nullptr)
      x->lch->add += x->add;
    if (x->rch != nullptr)
      x->rch->add += x->add;
    x->add = 0;
  }

  if (x->rev) {
    swap(x->lch, x->rch);
    if (x->lch != nullptr)
      x->lch->rev ^= true;
    if (x->rch != nullptr)
      x->rch->rev ^= true;
    x->rev = false;
  }

  return x;
}

Node *merge(Node *l, Node *r) {
  l = update(l), r = update(r);
  if (l == nullptr)
    return r;
  if (r == nullptr)
    return l;

  if (l->pri > r->pri) {
    l->rch = merge(l->rch, r);
    return update(l);
  } else {
    r->lch = merge(l, r->lch);
    return update(r);
  }
}

tuple<Node *, Node *> split(Node *x, int k) { //[0,k) [k,n)
  if (update(x) == nullptr)
    return make_tuple(nullptr, nullptr);

  Node *l, *r;
  if (k <= cnt(x->lch)) {
    tie(l, r) = split(x->lch, k);
    x->lch = r;
    return make_tuple(update(l), update(x));
  } else {
    tie(l, r) = split(x->rch, k - cnt(x->lch) - 1);
    x->rch = l;
    return make_tuple(update(x), update(r));
  }
}

Node *range_merge(Node *left, Node *tar, Node *right) {
  return merge(left, merge(tar, right));
}

tuple<Node *, Node *, Node *> range_split(Node *t, int l, int r) {
  Node *left, *tar, *right;
  tie(tar, right) = split(t, r);
  tie(left, tar) = split(tar, l);
  return make_tuple(left, tar, right);
}

void insert(Node *t, int k, int v) {
  Node *left, *right, *tar = create(v);
  tie(left, right) = split(t, k);
  t = range_merge(left, tar, right);
}

void erase(Node *t, int k) {
  Node *left, *tar, *right;
  tie(left, tar, right) = range_split(t, k, k + 1);
  t = merge(left, right);
}

void shift(Node *t, int l, int r) {
  Node *left, *tar, *right;
  tie(left, tar, right) = range_split(t, l, r);
  Node *tar_l, *tar_r;
  tie(tar_l, tar_r) = split(tar, cnt(tar) - 1);
  tar = merge(tar_r, tar_l);
  t = range_merge(left, tar, right);
}

int min(Node *t, int l, int r) {
  Node *left, *tar, *right;
  tie(left, tar, right) = range_split(t, l, r);
  int ret = tar->min;
  t = range_merge(left, tar, right);
  return ret;
}

void change(Node *t, int p, int v) {
  erase(t, p);
  insert(t, p, v);
}

int main(void) {
  int n, q;
  cin >> n >> q;

  Node *t = nullptr;

  rep(i, n) {
    int in;
    cin >> in;
    t = merge(t, create(in));
  }

  rep(loop, q) {
    int type, a, b;
    cin >> type >> a >> b;
    if (type == 0)
      shift(t, a, b + 1);
    else if (type == 1)
      cout << min(t, a, b + 1) << endl;
    else
      change(t, a, b);
  }
  return 0;
}