Problem p00998 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <forward_list>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using ll = long long;
#define rep(j, k) for (int j = 0; j < (int)(k); j++)

struct Random {
  uint32_t seed;
  Random(uint32_t s = 0) { seed = (uint32_t)time(0) + 1145141919; }
  uint32_t next() {
    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = seed;
    uint32_t t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
    return w;
  }
  int32_t nextInt(int32_t l, int32_t r) { return l + next() % (r - l + 1); }
  int32_t nextInt(int r) { return next() % r; }
  template <int mask> int32_t nextInt() { return next() & mask; }
  double nextDouble() { return next() * 0.00000000023283064365386962890625; }
  double nextDouble(double r) {
    return next() * 0.00000000023283064365386962890625 * r;
  }
};
#define rand @
Random rng;

namespace RBST {
using Key = int;

struct Node {
  Key key;
  Node *left, *right;
  int size;
  Key min;
};

const Key INF = 1e9;
using Np = Node *;
using pair = std::pair<Np, Np>;

const Np NIL = new Node{Key(), nullptr, nullptr, 0, INF};

int size(Np n) { return n->size; }

Key min(Np n) { return n->min; }

void update(Np n) {
  n->size = 1 + size(n->left) + size(n->right);
  n->min = std::min({min(n->left), n->key, min(n->right)});
}

void assign(Np n, int k, Key x) {
  if (k < size(n->left))
    assign(n->left, k, x);
  else if (size(n->left) == k)
    n->key = x;
  else
    assign(n->right, k - size(n->left) - 1, x);
  update(n);
}

Key min(Np n, int l, int r) {
  l = std::max(l, 0);
  r = std::min(r, size(n));
  if (l >= r)
    return INF;
  if (l == 0 && r == size(n))
    return min(n);

  Key res = INF;
  int sl = size(n->left);
  res = std::min(res, min(n->left, l, r));
  res = std::min(res, min(n->right, l - sl - 1, r - sl - 1));
  if (l <= sl && sl < r)
    res = std::min(res, n->key);
  return res;
}

Np merge(Np l, Np r) {
  if (l == NIL)
    return r;
  if (r == NIL)
    return l;
  int sl = size(l), sr = size(r);
  if (rng.next() % (sl + sr) >= sl) {
    l->right = merge(l->right, r);
    update(l);
    return l;
  } else {
    r->left = merge(l, r->left);
    update(r);
    return r;
  }
}

pair split(Np n, int k) {
  if (n == NIL)
    return {NIL, NIL};
  if (k <= size(n->left)) {
    pair p = split(n->left, k);
    n->left = p.second;
    update(n);
    return {p.first, n};
  } else {
    pair p = split(n->right, k - size(n->left) - 1);
    n->right = p.first;
    update(n);
    return {n, p.second};
  }
}

Np shift(Np n, int l, int r) {
  Np a, b, c, d;
  std::tie(a, b) = split(n, l);
  std::tie(b, c) = split(b, r - l);
  std::tie(c, d) = split(c, 1);
  return merge(merge(a, c), merge(b, d));
}

Np append(Np n, const Key &k) {
  static Node pool[200010];
  static int p = 0;
  Np a = pool + p++;
  *a = {k, NIL, NIL, 1, k};
  return merge(n, a);
}
}; // namespace RBST

using namespace std;
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n, q;
  cin >> n >> q;

  RBST::Node *root = RBST::NIL;

  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    root = RBST::append(root, a);
  }

  // Treap::show(root);

  for (int i = 0; i < q; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    if (x == 0) {
      root = RBST::shift(root, y, z);
    }
    if (x == 1) {
      // puts("=====");
      // Treap::show(root);
      cout << RBST::min(root, y, z + 1) << '\n';
    }
    if (x == 2) {
      RBST::assign(root, y, z);
    }
  }
}

Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <forward_list>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using ll = long long;
#define rep(j, k) for (int j = 0; j < (int)(k); j++)

struct Random {
  uint32_t seed;
  Random(uint32_t s = 0) { seed = (uint32_t)time(0) + 1145141919; }
  uint32_t next() {
    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = seed;
    uint32_t t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
    return w;
  }
  int32_t nextInt(int32_t l, int32_t r) { return l + next() % (r - l + 1); }
  int32_t nextInt(int r) { return next() % r; }
  template <int mask> int32_t nextInt() { return next() & mask; }
  double nextDouble() { return next() * 0.00000000023283064365386962890625; }
  double nextDouble(double r) {
    return next() * 0.00000000023283064365386962890625 * r;
  }
};
#define rand @
Random rng;

namespace RBST {
using Key = int;

struct Node {
  Key key;
  Node *left, *right;
  int size;
  Key min;
};

const Key INF = 1e9;
using Np = Node *;
using pair = std::pair<Np, Np>;

const Np NIL = new Node{Key(), nullptr, nullptr, 0, INF};

int size(Np n) { return n->size; }

Key min(Np n) { return n->min; }

void update(Np n) {
  n->size = 1 + size(n->left) + size(n->right);
  n->min = std::min({min(n->left), n->key, min(n->right)});
}

void assign(Np n, int k, Key x) {
  if (k < size(n->left))
    assign(n->left, k, x);
  else if (size(n->left) == k)
    n->key = x;
  else
    assign(n->right, k - size(n->left) - 1, x);
  update(n);
}

Key min(Np n, int l, int r) {
  l = std::max(l, 0);
  r = std::min(r, size(n));
  if (l >= r)
    return INF;
  if (l == 0 && r == size(n))
    return min(n);

  Key res = INF;
  int sl = size(n->left);
  res = std::min(res, min(n->left, l, r));
  res = std::min(res, min(n->right, l - sl - 1, r - sl - 1));
  if (l <= sl && sl < r)
    res = std::min(res, n->key);
  return res;
}

Np merge(Np l, Np r) {
  if (l == NIL)
    return r;
  if (r == NIL)
    return l;
  int sl = size(l), sr = size(r);
  if (rng.next() % (sl + sr) < sl) {
    l->right = merge(l->right, r);
    update(l);
    return l;
  } else {
    r->left = merge(l, r->left);
    update(r);
    return r;
  }
}

pair split(Np n, int k) {
  if (n == NIL)
    return {NIL, NIL};
  if (k <= size(n->left)) {
    pair p = split(n->left, k);
    n->left = p.second;
    update(n);
    return {p.first, n};
  } else {
    pair p = split(n->right, k - size(n->left) - 1);
    n->right = p.first;
    update(n);
    return {n, p.second};
  }
}

Np shift(Np n, int l, int r) {
  Np a, b, c, d;
  std::tie(a, b) = split(n, l);
  std::tie(b, c) = split(b, r - l);
  std::tie(c, d) = split(c, 1);
  return merge(merge(a, c), merge(b, d));
}

Np append(Np n, const Key &k) {
  static Node pool[200010];
  static int p = 0;
  Np a = pool + p++;
  *a = {k, NIL, NIL, 1, k};
  return merge(n, a);
}
}; // namespace RBST

using namespace std;
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n, q;
  cin >> n >> q;

  RBST::Node *root = RBST::NIL;

  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    root = RBST::append(root, a);
  }

  // Treap::show(root);

  for (int i = 0; i < q; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    if (x == 0) {
      root = RBST::shift(root, y, z);
    }
    if (x == 1) {
      // puts("=====");
      // Treap::show(root);
      cout << RBST::min(root, y, z + 1) << '\n';
    }
    if (x == 2) {
      RBST::assign(root, y, z);
    }
  }
}