Problem p02122 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(), (x).end())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); (i)++)
#define repn(i, a, n) for (int(i) = (a); (i) < (int)(n); (i)++)
#define EQ(a, b) (abs((a) - (b)) < eps)
typedef int val_t;
const int memory_limit = 8000000;
struct RBST {
  struct Node {
    Node *lp, *rp;
    int size;
    val_t val;
    val_t mini;
    Node() {}
    Node(val_t v) : val(v), mini(v), size(1), lp(NULL), rp(NULL) {}
    Node(Node *x)
        : val(x->val), mini(x->mini), size(x->size), lp(x->lp), rp(x->rp) {}
  };
  Node *root;
  RBST() : root(NULL), memory_size(0) {}
  Node pool[memory_limit + 10000];
  int memory_size;
  val_t str[400100];
  int length_limit;
  int id;
  int size(Node *x) { return !x ? 0 : x->size; }
  val_t min_(Node *x) { return !x ? INF : x->mini; }
  Node *update(Node *x) {
    if (x == NULL)
      return x;
    x->size = 1 + size(x->lp) + size(x->rp);
    x->mini = min(x->val, min(min_(x->lp), min_(x->rp)));
    return x;
  }
  Node *alloc(val_t val) { return &(pool[memory_size++] = Node(val)); }
  Node *copy(Node *x) { return &(pool[memory_size++] = Node(x)); }
  Node *merge(Node *x, Node *y) {
    if (x == NULL)
      return y;
    if (y == NULL)
      return x;
    int m = x->size, n = y->size;
    if (rand() % (m + n) < m) {
      x = copy(x);
      x->rp = merge(x->rp, y);
      return update(x);
    } else {
      y = copy(y);
      y->lp = merge(x, y->lp);
      return update(y);
    }
  }
  Node *merge_(Node *x, Node *y) {
    if (x == NULL)
      return y;
    if (y == NULL)
      return x;
    int m = x->size, n = y->size;
    if (rand() % (m + n) < m) {
      x->rp = merge(x->rp, y);
      return update(x);
    } else {
      y->lp = merge(x, y->lp);
      return update(y);
    }
  }
  typedef pair<Node *, Node *> Np;
  Np split(Node *x, int k) { //[0,k),[k,n)
    if (x == NULL)
      return Np(NULL, NULL);
    // assert(k<=(x->size));
    x = copy(x);
    if (k <= size(x->lp)) {
      Np s = split(x->lp, k);
      x->lp = s.sec;
      return mp(s.fi, update(x));
    } else {
      Np s = split(x->rp, k - size(x->lp) - 1);
      x->rp = s.fi;
      return mp(update(x), s.sec);
    }
  }
  void insert(int k, val_t val) { // 0-indexed
    Np s = split(root, k);
    root = merge(merge(s.fi, alloc(val)), s.sec);
    return;
  }
  val_t erase(int k) { // 0-indexed
    Np s = split(root, k);
    Np s2 = split(s.sec, 1);
    root = merge(s.fi, s2.sec);
    return s2.fi->val;
  }
  val_t query(int l, int r) { //[l,r)
    Np s = split(root, l);
    Np s2 = split(s.sec, r - l);
    val_t ret = min_(s2.fi);
    root = merge(merge(s.fi, s2.fi), s2.sec);
    return ret;
  }
  void copypaste(int a, int b, int c) { // 0-indexed [a,b)
    Np s = split(root, a);
    Np s2 = split(s.sec, b - a);
    Np s3 = split(root, c);
    root = merge(merge(s3.fi, s2.fi), s3.sec);
    if (size(root) > length_limit)
      root = split(root, length_limit).fi;
    return;
  }
  void copy_query1(int sz) {
    Np s = split(root, sz);
    Np s2 = split(root, sz);
    root = merge(s2.sec, s.sec);
  }
  void copy_query2(int sz) {
    Np s = split(root, sz);
    Np s2 = split(root, sz);
    root = merge(s.fi, s2.fi);
  }
  void write(Node *x) {
    if (x == NULL)
      return;
    write(x->lp);
    str[id++] = x->val;
    write(x->rp);
  }
  void output(Node *x) {
    if (x == NULL)
      return;
    printf("[");
    output(x->lp);
    printf("%d", x->val);
    output(x->rp);
    printf("]");
  }
  void build() {
    memory_size = 0;
    root = NULL;
    for (int i = 0; i < length_limit; i++)
      root = merge_(root, alloc(str[i]));
  }
  void rebuild() {
    id = 0;
    write(root);
    // assert(id==length_limit);
    build();
  }
  void show() {
    str[id] = -1;
    for (int i = 0; i < length_limit; i++)
      printf("%d ", str[i]);
    printf("\\n");
  }
} tree;
int main() {
  int N;
  scanf("%d", &N);
  tree.length_limit = 2 * N;
  for (int i = 0; i < N; i++)
    scanf("%d", &tree.str[i]);
  for (int i = 0; i < N; i++)
    scanf("%d", &tree.str[i + N]);
  tree.build();
  /*for(int i=0;i<2*N;i++){
          int a;
          scanf("%d",&a);
          tree.insert(i,a);
          //tree.output(tree.root);
          printf("\\n");
  }*/
  int Q;
  scanf("%d", &Q);
  for (int i = 0; i < Q; i++) {
    int type, y, z;
    scanf("%d", &type);
    scanf("%d %d", &y, &z);
    y--;
    if (type == 1) {
      tree.erase(y);
      tree.insert(y, z);
      // tree.output(tree.root);
      // printf("\\n");
    } else if (type == 2) {
      tree.erase(y + N);
      tree.insert(y + N, z);
    } else if (type == 3) {
      printf("%d\\n", tree.query(y, z));
    } else if (type == 4) {
      printf("%d\\n", tree.query(y + N, z + N));
    } else if (type == 5) {
      tree.copy_query1(N);
      // tree.output(tree.root);
    } else {
      tree.copy_query2(N);
      // tree.output(tree.root);
    }
    if (tree.memory_size > memory_limit)
      tree.rebuild();
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(), (x).end())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); (i)++)
#define repn(i, a, n) for (int(i) = (a); (i) < (int)(n); (i)++)
#define EQ(a, b) (abs((a) - (b)) < eps)
typedef int val_t;
const int memory_limit = 9000000;
struct RBST {
  struct Node {
    Node *lp, *rp;
    int size;
    val_t val;
    val_t mini;
    Node() {}
    Node(val_t v) : val(v), mini(v), size(1), lp(NULL), rp(NULL) {}
    Node(Node *x)
        : val(x->val), mini(x->mini), size(x->size), lp(x->lp), rp(x->rp) {}
  };
  Node *root;
  RBST() : root(NULL), memory_size(0) {}
  Node pool[memory_limit + 10000];
  int memory_size;
  val_t str[700100];
  int length_limit;
  int id;
  int size(Node *x) { return !x ? 0 : x->size; }
  val_t min_(Node *x) { return !x ? INF : x->mini; }
  Node *update(Node *x) {
    if (x == NULL)
      return x;
    x->size = 1 + size(x->lp) + size(x->rp);
    x->mini = min(x->val, min(min_(x->lp), min_(x->rp)));
    return x;
  }
  Node *alloc(val_t val) { return &(pool[memory_size++] = Node(val)); }
  Node *copy(Node *x) { return &(pool[memory_size++] = Node(x)); }
  Node *merge(Node *x, Node *y) {
    if (x == NULL)
      return y;
    if (y == NULL)
      return x;
    int m = x->size, n = y->size;
    if (rand() % (m + n) < m) {
      x = copy(x);
      x->rp = merge(x->rp, y);
      return update(x);
    } else {
      y = copy(y);
      y->lp = merge(x, y->lp);
      return update(y);
    }
  }
  Node *merge_(Node *x, Node *y) {
    if (x == NULL)
      return y;
    if (y == NULL)
      return x;
    int m = x->size, n = y->size;
    if (rand() % (m + n) < m) {
      x->rp = merge(x->rp, y);
      return update(x);
    } else {
      y->lp = merge(x, y->lp);
      return update(y);
    }
  }
  typedef pair<Node *, Node *> Np;
  Np split(Node *x, int k) { //[0,k),[k,n)
    if (x == NULL)
      return Np(NULL, NULL);
    // assert(k<=(x->size));
    x = copy(x);
    if (k <= size(x->lp)) {
      Np s = split(x->lp, k);
      x->lp = s.sec;
      return mp(s.fi, update(x));
    } else {
      Np s = split(x->rp, k - size(x->lp) - 1);
      x->rp = s.fi;
      return mp(update(x), s.sec);
    }
  }
  void insert(int k, val_t val) { // 0-indexed
    Np s = split(root, k);
    root = merge(merge(s.fi, alloc(val)), s.sec);
    return;
  }
  val_t erase(int k) { // 0-indexed
    Np s = split(root, k);
    Np s2 = split(s.sec, 1);
    root = merge(s.fi, s2.sec);
    return s2.fi->val;
  }
  val_t query(int l, int r) { //[l,r)
    Np s = split(root, l);
    Np s2 = split(s.sec, r - l);
    val_t ret = min_(s2.fi);
    root = merge(merge(s.fi, s2.fi), s2.sec);
    return ret;
  }
  void copypaste(int a, int b, int c) { // 0-indexed [a,b)
    Np s = split(root, a);
    Np s2 = split(s.sec, b - a);
    Np s3 = split(root, c);
    root = merge(merge(s3.fi, s2.fi), s3.sec);
    if (size(root) > length_limit)
      root = split(root, length_limit).fi;
    return;
  }
  void copy_query1(int sz) {
    Np s = split(root, sz);
    Np s2 = split(root, sz);
    root = merge(s2.sec, s.sec);
  }
  void copy_query2(int sz) {
    Np s = split(root, sz);
    Np s2 = split(root, sz);
    root = merge(s.fi, s2.fi);
  }
  void write(Node *x) {
    if (x == NULL)
      return;
    write(x->lp);
    str[id++] = x->val;
    write(x->rp);
  }
  void output(Node *x) {
    if (x == NULL)
      return;
    printf("[");
    output(x->lp);
    printf("%d", x->val);
    output(x->rp);
    printf("]");
  }
  void build() {
    memory_size = 0;
    root = NULL;
    for (int i = 0; i < length_limit; i++)
      root = merge_(root, alloc(str[i]));
  }
  void rebuild() {
    id = 0;
    write(root);
    // assert(id==length_limit);
    build();
  }
  void show() {
    str[id] = -1;
    for (int i = 0; i < length_limit; i++)
      printf("%d ", str[i]);
    printf("\\n");
  }
} tree;
int main() {
  int N;
  scanf("%d", &N);
  tree.length_limit = 2 * N;
  for (int i = 0; i < N; i++)
    scanf("%d", &tree.str[i]);
  for (int i = 0; i < N; i++)
    scanf("%d", &tree.str[i + N]);
  tree.build();
  /*for(int i=0;i<2*N;i++){
          int a;
          scanf("%d",&a);
          tree.insert(i,a);
          //tree.output(tree.root);
          printf("\\n");
  }*/
  int Q;
  scanf("%d", &Q);
  for (int i = 0; i < Q; i++) {
    int type, y, z;
    scanf("%d", &type);
    scanf("%d %d", &y, &z);
    y--;
    if (type == 1) {
      tree.erase(y);
      tree.insert(y, z);
      // tree.output(tree.root);
      // printf("\\n");
    } else if (type == 2) {
      tree.erase(y + N);
      tree.insert(y + N, z);
    } else if (type == 3) {
      printf("%d\\n", tree.query(y, z));
    } else if (type == 4) {
      printf("%d\\n", tree.query(y + N, z + N));
    } else if (type == 5) {
      tree.copy_query1(N);
      // tree.output(tree.root);
    } else {
      tree.copy_query2(N);
      // tree.output(tree.root);
    }
    if (tree.memory_size > memory_limit)
      tree.rebuild();
  }
  return 0;
}