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

#include <bits/stdc++.h>
// #ifdef CHECK_

template <typename T> T get() { return 0; }
template <> int get() {
  int x;
  scanf("%d", &x);
  return x;
}
template <> long get() {
  long x;
  scanf("%ld", &x);
  return x;
}

template <typename T> void put(T x) {}
template <> void put(int x) { printf("%d\\n", x); }
template <> void put(long x) { printf("%ld\\n", x); }
template <> void put(std::string str) { printf("%s\\n", str.c_str()); }
template <> void put(const char *str) { printf("%s\\n", str); }

class Node {
public:
  Node *left, *right;
  int num;
  int value;
  int min;
  Node() {}
};

class NodeHeap {
public:
  std::vector<Node *> xss;
  int n;
  NodeHeap() : n(262144) {}
  Node *next() {
    if (n == 262144) {
      n = 0;
      Node *p = new Node[262144];
      xss.push_back(p);
    }
    return &xss[xss.size() - 1][n++];
  }
};
NodeHeap nheap;

Node *initLeaf(int v) {
  // Node *res = new Node;
  Node *res = nheap.next();
  res->left = res->right = nullptr;
  res->num = 1;
  res->value = v;
  res->min = v;
  return res;
}

Node *initNode(Node *base, Node *left, Node *right) {
#ifdef Persistent
  // Node *res = new Node;
  Node *res = nheap.next();
#else
  Node *res = base != nullptr ? base : nheap.next();
#endif
  res->left = left;
  res->right = right;
  res->num = 0;
  res->value = 0;
  res->min = (1 << 30);
  return res;
}

bool isLeaf(Node *p) {
  if (p == nullptr)
    return false;
  return p->left == nullptr and p->right == nullptr;
}

int getNum(Node *p) {
  if (p == nullptr)
    return 0;
  if (isLeaf(p))
    return 1;
  return p->num;
}

Node *getLeft(Node *p) {
  if (p == nullptr)
    return nullptr;
  return p->left;
}

Node *getRight(Node *p) {
  if (p == nullptr)
    return nullptr;
  return p->right;
}

int getValue(Node *p) {
  if (p == nullptr)
    return (1 << 30);
  // assert( p != nullptr );
  return p->value;
}

int getMin(Node *p) {
  if (p == nullptr)
    return (1 << 30);
  return p->min;
}

// checker
void dump2(Node *node) {
  if (node == nullptr)
    return;
  if (node->left == nullptr and node->right == nullptr) {
    printf("{%d,%d}", node->value, node->min);
    return;
  }
  printf("(%d,%d)[", node->num, node->min);
  dump2(node->left);
  putchar(',');
  dump2(node->right);
  putchar(']');
}

Node *dump(Node *node) {
  dump2(node);
  putchar('\\n');
  return node;
}

int maxDepth(Node *node) {
  if (node == nullptr)
    return -1;
  if (isLeaf(node))
    return 0;
  return 1 + std::max(maxDepth(getLeft(node)), maxDepth(getRight(node)));
}

Node *update(Node *p) {
  if (p == nullptr)
    return nullptr;
  assert(not isLeaf(p));
  p->num = getNum(getLeft(p)) + getNum(getRight(p));
  if (isLeaf(p)) {
    p->min = p->value;
  } else {
    p->min = std::min(getMin(getLeft(p)), getMin(getRight(p)));
  }
  return p;
}

Node *merge(Node *left, Node *right) {
  if (left == nullptr and right == nullptr)
    return nullptr;
  if (isLeaf(left) and isLeaf(right))
    return update(initNode(nullptr, left, right));
  if (left == nullptr) {
    if (isLeaf(right)) {
      return right;
    } else {
      // return initNode(nullptr, getLeft(right), getRight(right));
    }
  }
  if (right == nullptr) {
    if (isLeaf(left)) {
      return left;
    } else {
      // return initNode(nullptr, getLeft(left), getRight(left));
    }
  }
  // if( left == nullptr and isLeaf(right) ) return right;
  // if( right == nullptr and isLeaf(left) ) return left;
  if (left == nullptr or right == nullptr)
    return update(initNode(nullptr, left, right));
  if (getNum(left) < getNum(right) or
      (getNum(left) == getNum(right) and rand() % 2 == 0)) {
    if (isLeaf(right))
      return update(initNode(nullptr, left, right));
    // left merged
    Node *w = merge(left, getLeft(right));
    Node *v = initNode(right, w, getRight(right));
    // assert( not isLeaf(v) );
    if (isLeaf(w) or w == nullptr)
      return update(v);
    // assert( not isLeaf(w) );
    // if( isLeaf(w) ) return update(v);
    // rotate right only
    // right
    if (getNum(getLeft(w)) - getNum(getRight(v)) > 0) {
      v->left = getRight(w);
      w->right = v;
      update(v);
      return update(w);
    }
    if (getNum(getLeft(getRight(w))) + getNum(getRight(getRight(w))) -
            getNum(getRight(v)) >
        0) {
      Node *ml = getLeft(getRight(w));
      Node *mr = getRight(getRight(w));
      Node *x = initNode(w->right, w, v);
      w->right = ml;
      v->left = mr;
      update(w);
      update(v);
      return update(x);
    }
    return update(v);
  } else {
    if (isLeaf(left))
      return update(initNode(nullptr, left, right));
    Node *w = merge(getRight(left), right);
    Node *v = initNode(left, getLeft(left), w);
    // assert( not isLeaf(v) );
    // assert( not isLeaf(w) );
    if (isLeaf(w) or w == nullptr)
      return update(v);
    // rotate left only
    // left
    if (getNum(getRight(w)) - getNum(getLeft(v)) > 0) {
      v->right = getLeft(w);
      w->left = v;
      update(v);
      return update(w);
    }
    if (getNum(getLeft(getLeft(w))) + getNum(getRight(getLeft(w))) -
            getNum(getLeft(v)) >
        0) {
      Node *ml = getLeft(getLeft(w));
      Node *mr = getRight(getLeft(w));
      Node *x = initNode(getLeft(w), v, w);
      v->right = ml;
      w->left = mr;
      update(v);
      update(w);
      return update(x);
    }
    return update(v);
  }
}

// [0, k), [k, size)
std::pair<Node *, Node *> split(Node *p, int k) {
  if (getNum(p) == k)
    return std::pair<Node *, Node *>(p, nullptr);
  if (k == 0)
    return std::pair<Node *, Node *>(nullptr, p);
  if (k <= getNum(getLeft(p))) {
    Node *left, *right;
    std::tie(left, right) = split(getLeft(p), k);
    return std::pair<Node *, Node *>(left, merge(right, getRight(p)));
  } else {
    Node *left, *right;
    std::tie(left, right) = split(getRight(p), k - getNum(getLeft(p)));
    return std::pair<Node *, Node *>(merge(getLeft(p), left), right);
  }
}

// [l, r)
int minimum(Node *p, int l, int r) {
  if (isLeaf(p))
    return p->value;
  if (l == 0 and r == getNum(p))
    return p->min;
  if (r <= getNum(getLeft(p))) {
    return minimum(getLeft(p), l, r);
  } else if (getNum(getLeft(p)) <= l) {
    return minimum(getRight(p), l - getNum(getLeft(p)), r - getNum(getLeft(p)));
  } else {
    int leftmin = minimum(getLeft(p), l, getNum(getLeft(p)));
    int rightmin = minimum(getRight(p), 0, r - getNum(getLeft(p)));
    return std::min(leftmin, rightmin);
  }
}

int main() {
  Node *root = nullptr;
  int n = get<int>();
  int q = get<int>();
  for (int i = 0; i < n; ++i) {
    int a = get<int>();
    root = merge(root, initLeaf(a));
    // dump(root);
  }
  for (int i = 0; i < q; ++i) {
    const int x = get<int>();
    int y = get<int>();
    int z = get<int>();
    if (x == 0) {
      Node *nl, *nr;
      std::tie(nl, nr) = split(root, z + 1);
      Node *nll, *nlr;
      std::tie(nll, nlr) = split(nl, z);
      Node *nlll, *nllr;
      std::tie(nlll, nllr) = split(nll, y);
      root = merge(merge(merge(nlll, nlr), nllr), nr);
    }
    if (x == 1) {
      int res = minimum(root, y, z + 1);
      printf("%d\\n", res);
    }
    if (x == 2) {
      Node *nl, *nr;
      std::tie(nl, nr) = split(root, y + 1);
      Node *nll, *nlr;
      std::tie(nll, nlr) = split(nl, y);
      root = merge(merge(nll, initLeaf(z)), nr);
    }
    // dump(root);
  }
  // int t = getNum(root);
  // root = merge(root, root);
  // dump(root);
  // root = split(root, t).first;
  // dump(root);
  // for(int i = 0; i < 17; ++i) {
  //   root = merge(root, root);
  // }
  // printf("numnode  : %d\\n", getNum(root));
  // printf("maxdepth : %d\\n", maxDepth(root));

  return 0;
}

// #else

// template<typename T>
// T get() { return 0; }
// template<>
// int get() { int x; scanf("%d", &x); return x; }
// template<>
// long get() { long x; scanf("%ld", &x); return x; }

// template<typename T>
// void put(T x) {}
// template<>
// void put(int x) { printf("%d\\n", x); }
// template<>
// void put(long x) { printf("%ld\\n", x); }
// template<>
// void put(std::string str) { printf("%s\\n", str.c_str()); }
// template<>
// void put(const char* str) { printf("%s\\n", str); }

// #define CHECK_
// #include __FILE__
// #endif

Error: 0

Fixed submission:

#include <bits/stdc++.h>
// #ifdef CHECK_

template <typename T> T get() { return 0; }
template <> int get() {
  int x;
  scanf("%d", &x);
  return x;
}
template <> long get() {
  long x;
  scanf("%ld", &x);
  return x;
}

template <typename T> void put(T x) {}
template <> void put(int x) { printf("%d\\n", x); }
template <> void put(long x) { printf("%ld\\n", x); }
template <> void put(std::string str) { printf("%s\\n", str.c_str()); }
template <> void put(const char *str) { printf("%s\\n", str); }

class Node {
public:
  Node *left, *right;
  int num;
  int value;
  int min;
  Node() {}
};

class NodeHeap {
public:
  std::vector<Node *> xss;
  int n;
  NodeHeap() : n(262144) {}
  Node *next() {
    if (n == 262144) {
      n = 0;
      Node *p = new Node[262144];
      xss.push_back(p);
    }
    return &xss[xss.size() - 1][n++];
  }
};
NodeHeap nheap;

Node *initLeaf(int v) {
  // Node *res = new Node;
  Node *res = nheap.next();
  res->left = res->right = nullptr;
  res->num = 1;
  res->value = v;
  res->min = v;
  return res;
}

Node *initNode(Node *base, Node *left, Node *right) {
#ifdef Persistent
  // Node *res = new Node;
  Node *res = nheap.next();
#else
  Node *res = base != nullptr ? base : nheap.next();
#endif
  res->left = left;
  res->right = right;
  res->num = 0;
  res->value = 0;
  res->min = (1 << 30);
  return res;
}

bool isLeaf(Node *p) {
  if (p == nullptr)
    return false;
  return p->left == nullptr and p->right == nullptr;
}

int getNum(Node *p) {
  if (p == nullptr)
    return 0;
  if (isLeaf(p))
    return 1;
  return p->num;
}

Node *getLeft(Node *p) {
  if (p == nullptr)
    return nullptr;
  return p->left;
}

Node *getRight(Node *p) {
  if (p == nullptr)
    return nullptr;
  return p->right;
}

int getValue(Node *p) {
  if (p == nullptr)
    return (1 << 30);
  // assert( p != nullptr );
  return p->value;
}

int getMin(Node *p) {
  if (p == nullptr)
    return (1 << 30);
  return p->min;
}

// checker
void dump2(Node *node) {
  if (node == nullptr)
    return;
  if (node->left == nullptr and node->right == nullptr) {
    printf("{%d,%d}", node->value, node->min);
    return;
  }
  printf("(%d,%d)[", node->num, node->min);
  dump2(node->left);
  putchar(',');
  dump2(node->right);
  putchar(']');
}

Node *dump(Node *node) {
  dump2(node);
  putchar('\\n');
  return node;
}

int maxDepth(Node *node) {
  if (node == nullptr)
    return -1;
  if (isLeaf(node))
    return 0;
  return 1 + std::max(maxDepth(getLeft(node)), maxDepth(getRight(node)));
}

Node *update(Node *p) {
  if (p == nullptr)
    return nullptr;
  assert(not isLeaf(p));
  p->num = getNum(getLeft(p)) + getNum(getRight(p));
  if (isLeaf(p)) {
    p->min = p->value;
  } else {
    p->min = std::min(getMin(getLeft(p)), getMin(getRight(p)));
  }
  return p;
}

Node *merge(Node *left, Node *right) {
  if (left == nullptr and right == nullptr)
    return nullptr;
  if (isLeaf(left) and isLeaf(right))
    return update(initNode(nullptr, left, right));
  if (left == nullptr) {
    if (isLeaf(right)) {
      return right;
    } else {
      return initNode(nullptr, getLeft(right), getRight(right));
    }
  }
  if (right == nullptr) {
    if (isLeaf(left)) {
      return left;
    } else {
      return initNode(nullptr, getLeft(left), getRight(left));
    }
  }
  // if( left == nullptr and isLeaf(right) ) return right;
  // if( right == nullptr and isLeaf(left) ) return left;
  // if( left == nullptr or right == nullptr ) return update(initNode(nullptr,
  // left, right));
  if (getNum(left) < getNum(right) or
      (getNum(left) == getNum(right) and rand() % 2 == 0)) {
    if (isLeaf(right))
      return update(initNode(nullptr, left, right));
    // left merged
    Node *w = merge(left, getLeft(right));
    Node *v = initNode(right, w, getRight(right));
    // assert( not isLeaf(v) );
    if (isLeaf(w) or w == nullptr)
      return update(v);
    // assert( not isLeaf(w) );
    // if( isLeaf(w) ) return update(v);
    // rotate right only
    // right
    if (getNum(getLeft(w)) - getNum(getRight(v)) > 0) {
      v->left = getRight(w);
      w->right = v;
      update(v);
      return update(w);
    }
    if (getNum(getLeft(getRight(w))) + getNum(getRight(getRight(w))) -
            getNum(getRight(v)) >
        0) {
      Node *ml = getLeft(getRight(w));
      Node *mr = getRight(getRight(w));
      Node *x = initNode(w->right, w, v);
      w->right = ml;
      v->left = mr;
      update(w);
      update(v);
      return update(x);
    }
    return update(v);
  } else {
    if (isLeaf(left))
      return update(initNode(nullptr, left, right));
    Node *w = merge(getRight(left), right);
    Node *v = initNode(left, getLeft(left), w);
    // assert( not isLeaf(v) );
    // assert( not isLeaf(w) );
    if (isLeaf(w) or w == nullptr)
      return update(v);
    // rotate left only
    // left
    if (getNum(getRight(w)) - getNum(getLeft(v)) > 0) {
      v->right = getLeft(w);
      w->left = v;
      update(v);
      return update(w);
    }
    if (getNum(getLeft(getLeft(w))) + getNum(getRight(getLeft(w))) -
            getNum(getLeft(v)) >
        0) {
      Node *ml = getLeft(getLeft(w));
      Node *mr = getRight(getLeft(w));
      Node *x = initNode(getLeft(w), v, w);
      v->right = ml;
      w->left = mr;
      update(v);
      update(w);
      return update(x);
    }
    return update(v);
  }
}

// [0, k), [k, size)
std::pair<Node *, Node *> split(Node *p, int k) {
  if (getNum(p) == k)
    return std::pair<Node *, Node *>(p, nullptr);
  if (k == 0)
    return std::pair<Node *, Node *>(nullptr, p);
  if (k <= getNum(getLeft(p))) {
    Node *left, *right;
    std::tie(left, right) = split(getLeft(p), k);
    return std::pair<Node *, Node *>(left, merge(right, getRight(p)));
  } else {
    Node *left, *right;
    std::tie(left, right) = split(getRight(p), k - getNum(getLeft(p)));
    return std::pair<Node *, Node *>(merge(getLeft(p), left), right);
  }
}

// [l, r)
int minimum(Node *p, int l, int r) {
  if (isLeaf(p))
    return p->value;
  if (l == 0 and r == getNum(p))
    return p->min;
  if (r <= getNum(getLeft(p))) {
    return minimum(getLeft(p), l, r);
  } else if (getNum(getLeft(p)) <= l) {
    return minimum(getRight(p), l - getNum(getLeft(p)), r - getNum(getLeft(p)));
  } else {
    int leftmin = minimum(getLeft(p), l, getNum(getLeft(p)));
    int rightmin = minimum(getRight(p), 0, r - getNum(getLeft(p)));
    return std::min(leftmin, rightmin);
  }
}

int main() {
  Node *root = nullptr;
  int n = get<int>();
  int q = get<int>();
  for (int i = 0; i < n; ++i) {
    int a = get<int>();
    root = merge(root, initLeaf(a));
    // dump(root);
  }
  for (int i = 0; i < q; ++i) {
    const int x = get<int>();
    int y = get<int>();
    int z = get<int>();
    if (x == 0) {
      Node *nl, *nr;
      std::tie(nl, nr) = split(root, z + 1);
      Node *nll, *nlr;
      std::tie(nll, nlr) = split(nl, z);
      Node *nlll, *nllr;
      std::tie(nlll, nllr) = split(nll, y);
      root = merge(merge(merge(nlll, nlr), nllr), nr);
    }
    if (x == 1) {
      int res = minimum(root, y, z + 1);
      printf("%d\\n", res);
    }
    if (x == 2) {
      Node *nl, *nr;
      std::tie(nl, nr) = split(root, y + 1);
      Node *nll, *nlr;
      std::tie(nll, nlr) = split(nl, y);
      root = merge(merge(nll, initLeaf(z)), nr);
    }
    // dump(root);
  }
  // int t = getNum(root);
  // root = merge(root, root);
  // dump(root);
  // root = split(root, t).first;
  // dump(root);
  // for(int i = 0; i < 17; ++i) {
  //   root = merge(root, root);
  // }
  // printf("numnode  : %d\\n", getNum(root));
  // printf("maxdepth : %d\\n", maxDepth(root));

  return 0;
}

// #else

// template<typename T>
// T get() { return 0; }
// template<>
// int get() { int x; scanf("%d", &x); return x; }
// template<>
// long get() { long x; scanf("%ld", &x); return x; }

// template<typename T>
// void put(T x) {}
// template<>
// void put(int x) { printf("%d\\n", x); }
// template<>
// void put(long x) { printf("%ld\\n", x); }
// template<>
// void put(std::string str) { printf("%s\\n", str.c_str()); }
// template<>
// void put(const char* str) { printf("%s\\n", str); }

// #define CHECK_
// #include __FILE__
// #endif