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

#include <algorithm>
#include <array>
#include <climits>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using uintl32 = std::uint_least32_t;
using intl32 = std::int_least32_t;

template <typename Monoid> class avl_tree {
  static constexpr uint64 allocsize = (uint64)1 << 14;
  struct node_t {
    node_t *left, *right;
    Monoid value, sum;
    intl32 height;
    uintl32 size, ref;
    void gc(void) {
      left->reset();
      right->reset();
      left = garbage;
      garbage = this;
    }
    void reset(void) {
      if (!(--ref))
        gc();
    }
  };
  static node_t *garbage;
  static node_t *data_;
  static node_t nil;
  node_t *root_;
  avl_tree(node_t *root) : root_(root) { ++root->ref; }
  static node_t *alloc(void) {
    if (!garbage) {
      garbage = (node_t *)malloc(allocsize * (uint64)sizeof(node_t));
      uint32 i = allocsize;
      (garbage + i - 1)->left = nullptr;
      while (--i) {
        (garbage + i - 1)->left = (garbage + i);
      }
    }
    node_t *ret = garbage;
    garbage = garbage->left;
    return ret;
  }
  static node_t *make(node_t *l, node_t *r, Monoid &m) {
    node_t *ret = alloc();
    ret->left = l;
    ret->right = r;
    ret->value = m;
    ret->sum = (l->sum + m) + r->sum;
    ret->height = std::max(l->height, r->height) + 1;
    ret->size = l->size + r->size + 1;
    ret->ref = 0;
    ++l->ref;
    ++r->ref;
    return ret;
  }
  static node_t *adjustR(node_t *n) {
    if (n->right->height - n->left->height != 2)
      return n;
    if (n->right->right->height + 2 == n->right->height) {
      node_t *t = n->right->left;
      t = make(make(n->left, t->left, n->value),
               make(t->right, n->right->right, n->right->value), t->value);
      n->gc();
      return t;
    } else {
      node_t *t = n->right;
      t = make(make(n->left, t->left, n->value), t->right, t->value);
      n->gc();
      return t;
    }
  }
  static node_t *adjustL(node_t *n) {
    if (n->left->height - n->right->height != 2)
      return n;
    if (n->left->left->height + 2 == n->left->height) {
      node_t *t = n->left->right;
      t = make(make(n->left->left, t->left, n->left->value),
               make(t->right, n->right, n->value), t->value);
      n->gc();
      return t;
    } else {
      node_t *t = n->left;
      t = make(t->left, make(t->right, n->right, n->value), t->value);
      n->gc();
      return t;
    }
  }
  static node_t *insert_(node_t *n, uint32 position) {
    if (n == &nil)
      return data_;
    if (n->left->size < position) {
      return adjustR(make(
          n->left, insert_(n->right, position - n->left->size - 1), n->value));
    } else {
      return adjustL(make(insert_(n->left, position), n->right, n->value));
    }
  }
  static node_t *erase_(node_t *n, uint32 position) {
    if (n->left->size > position) {
      return adjustR(make(erase_(n->left, position), n->right, n->value));
    } else if (n->left->size < position) {
      return adjustL(make(
          n->left, erase_(n->right, position - n->left->size - 1), n->value));
    }
    if (n->left == &nil) {
      data_ = n;
      if (n->right == &nil) {
        return &nil;
      } else {
        return make(&nil, &nil, n->right->value);
      }
    } else {
      if (n->right == &nil) {
        return make(&nil, &nil, n->left->value);
      } else {
        node_t *t = erase_(n->right, 0);
        return adjustL(make(n->left, t, data_->value));
      }
    }
  }
  static Monoid more_than(node_t *n, uint32 position) {
    Monoid ret;
    while (n != &nil) {
      if (n->left->size < position) {
        position -= n->left->size + 1;
        n = n->right;
      } else {
        ret = (n->value + n->right->sum) + ret;
        n = n->left;
      }
    }
    return ret;
  }
  static Monoid less_than(node_t *n, uint32 position) {
    Monoid ret;
    while (n != &nil) {
      if (n->left->size < position) {
        position -= n->left->size + 1;
        ret = ret + (n->left->sum + n->value);
        n = n->right;
      } else {
        n = n->left;
      }
    }
    return ret;
  }
  static void show_(node_t *n) {
    std::cout << "(";
    if (n->left != &nil) {
      show_(n->left);
      std::cout << "←";
    }
    std::cout << n->value.e << " " << n->height;
    if (n->right != &nil) {
      std::cout << "→";
      show_(n->right);
    }
    std::cout << ")";
  }

public:
  avl_tree() : root_(&nil) { ++nil.ref; }
  avl_tree(const avl_tree &other) : root_(other.root_) { ++root_->ref; }
  avl_tree &operator=(const avl_tree &other) {
    root_->reset();
    root_ = other.root_;
    ++root_->ref;
    return *this;
  }
  ~avl_tree() { root_->reset(); }
  Monoid access(uint32 index) {
    node_t *n = root_;
    while (index != n->left->size) {
      if (n->left->size < index) {
        index -= n->left->size + 1;
        n = n->right;
      } else {
        n = n->left;
      }
    }
    return n->value;
  }
  static avl_tree merge(const avl_tree &L, const avl_tree &R) {
    node_t *n = merge(L->root_, R->root_);
    return avl_tree(n);
  }
  std::pair<avl_tree, avl_tree> split(uint32 position) {
    std::pair<node_t *, node_t *> n = split(root_, position);
    return {avl_tree(n.first), avl_tree(n.second)};
  }
  avl_tree insert(uint32 position, Monoid data) {
    data_ = make(&nil, &nil, data);
    node_t *n = insert_(root_, position);
    return avl_tree(n);
  }
  avl_tree erase(uint32 position) { return avl_tree(erase_(root_, position)); }
  static avl_tree singlton(Monoid data) {
    return avl_tree(make(&nil, &nil, data));
  }
  Monoid range(uint32 begin, uint32 end) {
    if (begin >= end)
      return Monoid();
    node_t *n = root_;
    while (1) {
      if (n->left->size >= begin) {
        if (n->left->size < end)
          return (more_than(n->left, begin) + n->value) +
                 less_than(n->right, end - n->left->size - 1);
        n = n->left;
      } else {
        begin -= n->left->size + 1;
        end -= n->left->size + 1;
        n = n->right;
      }
    }
  }
  uint32 size(void) { return root_->size; }
  void show() {
    show_(root_);
    std::cout << "\\n";
  }
};
template <typename Monoid>
typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::garbage = nullptr;
template <typename Monoid>
typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::data_ = nullptr;
template <typename Monoid>
typename avl_tree<Monoid>::node_t avl_tree<Monoid>::nil = {
    &avl_tree<Monoid>::nil,
    &avl_tree<Monoid>::nil,
    Monoid(),
    Monoid(),
    0,
    0,
    100};
struct ADD {
  int64 e;
  ADD(int64 t = 0) { e = t; }
  ADD operator*(const ADD &other) { return ADD(e + other.e); }
};

struct SUM {
  int64 e;
  int64 s;
  SUM(int64 x = 0, int64 y = 1) {
    e = x;
    s = y;
  }
  void set() {
    e = 0;
    s = 1;
  }
  void reverse(void) {}
  SUM operator+(const SUM &other) { return SUM(e + other.e, s + other.s); };
  SUM operator*(const ADD &other) { return SUM(e + (s * other.e), s); }
};

int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  avl_tree<SUM> T;
  uint32 n, q;
  std::cin >> n >> q;
  for (uint32 i = 0; i < n; ++i) {
    T = T.insert(0, SUM());
  }
  uint32 c, x, y;
  while (q--) {
    std::cin >> c >> x >> y;
    if (c) {
      std::cout << T.range(x - 1, y).e << "\\n";
    } else {
      // T.show();
      avl_tree<SUM> V = T.erase(x - 1);
      // V.show();
      T = V.insert(x - 1, T.access(x - 1) + SUM(y));
    }
    // T.show();
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <climits>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using uintl32 = std::uint_least32_t;
using intl32 = std::int_least32_t;

template <typename Monoid> class avl_tree {
  static constexpr uint64 allocsize = (uint64)1 << 14;
  struct node_t {
    node_t *left, *right;
    Monoid value, sum;
    intl32 height;
    uintl32 size, ref;
    void gc(void) {
      // left->reset();
      // right->reset();
      // left = garbage;
      // garbage = this;
    }
    void reset(void) {
      if (!(--ref))
        gc();
    }
  };
  static node_t *garbage;
  static node_t *data_;
  static node_t nil;
  node_t *root_;
  avl_tree(node_t *root) : root_(root) { ++root->ref; }
  static node_t *alloc(void) {
    if (!garbage) {
      garbage = (node_t *)malloc(allocsize * (uint64)sizeof(node_t));
      uint32 i = allocsize;
      (garbage + i - 1)->left = nullptr;
      while (--i) {
        (garbage + i - 1)->left = (garbage + i);
      }
    }
    node_t *ret = garbage;
    garbage = garbage->left;
    return ret;
  }
  static node_t *make(node_t *l, node_t *r, Monoid &m) {
    node_t *ret = alloc();
    ret->left = l;
    ret->right = r;
    ret->value = m;
    ret->sum = (l->sum + m) + r->sum;
    ret->height = std::max(l->height, r->height) + 1;
    ret->size = l->size + r->size + 1;
    ret->ref = 0;
    ++l->ref;
    ++r->ref;
    return ret;
  }
  static node_t *adjustR(node_t *n) {
    if (n->right->height - n->left->height < 2)
      return n;
    if (n->right->right->height + 1 < n->right->height) {
      node_t *t = n->right->left;
      t = make(make(n->left, t->left, n->value),
               make(t->right, n->right->right, n->right->value), t->value);
      n->gc();
      return t;
    } else {
      node_t *t = n->right;
      t = make(make(n->left, t->left, n->value), t->right, t->value);
      n->gc();
      return t;
    }
  }
  static node_t *adjustL(node_t *n) {
    if (n->left->height - n->right->height < 2)
      return n;
    if (n->left->left->height + 1 < n->left->height) {
      node_t *t = n->left->right;
      t = make(make(n->left->left, t->left, n->left->value),
               make(t->right, n->right, n->value), t->value);
      n->gc();
      return t;
    } else {
      node_t *t = n->left;
      t = make(t->left, make(t->right, n->right, n->value), t->value);
      n->gc();
      return t;
    }
  }
  static node_t *insert_(node_t *n, uint32 position) {
    if (n == &nil)
      return data_;
    if (n->left->size < position) {
      return adjustR(make(
          n->left, insert_(n->right, position - n->left->size - 1), n->value));
    } else {
      return adjustL(make(insert_(n->left, position), n->right, n->value));
    }
  }
  static node_t *erase_(node_t *n, uint32 position) {
    if (n->left->size > position) {
      return adjustR(make(erase_(n->left, position), n->right, n->value));
    } else if (n->left->size < position) {
      return adjustL(make(
          n->left, erase_(n->right, position - n->left->size - 1), n->value));
    }
    if (n->left == &nil) {
      data_ = n;
      if (n->right == &nil) {
        return &nil;
      } else {
        return make(&nil, &nil, n->right->value);
      }
    } else {
      if (n->right == &nil) {
        return make(&nil, &nil, n->left->value);
      } else {
        node_t *t = erase_(n->right, 0);
        return adjustL(make(n->left, t, data_->value));
      }
    }
  }
  static Monoid more_than(node_t *n, uint32 position) {
    Monoid ret;
    while (n != &nil) {
      if (n->left->size < position) {
        position -= n->left->size + 1;
        n = n->right;
      } else {
        ret = (n->value + n->right->sum) + ret;
        n = n->left;
      }
    }
    return ret;
  }
  static Monoid less_than(node_t *n, uint32 position) {
    Monoid ret;
    while (n != &nil) {
      if (n->left->size < position) {
        position -= n->left->size + 1;
        ret = ret + (n->left->sum + n->value);
        n = n->right;
      } else {
        n = n->left;
      }
    }
    return ret;
  }
  static void show(node_t *n) {
    std::cout << "(";
    if (n->left != &nil) {
      show(n->left);
      std::cout << "←";
    }
    std::cout << n->value.e << " " << n->height;
    if (n->right != &nil) {
      std::cout << "→";
      show(n->right);
    }
    std::cout << ")";
  }

public:
  avl_tree() : root_(&nil) { ++nil.ref; }
  avl_tree(const avl_tree &other) : root_(other.root_) { ++root_->ref; }
  avl_tree &operator=(const avl_tree &other) {
    root_->reset();
    root_ = other.root_;
    ++root_->ref;
    return *this;
  }
  ~avl_tree() { root_->reset(); }
  Monoid access(uint32 index) {
    node_t *n = root_;
    while (index != n->left->size) {
      if (n->left->size < index) {
        index -= n->left->size + 1;
        n = n->right;
      } else {
        n = n->left;
      }
    }
    return n->value;
  }
  static avl_tree merge(const avl_tree &L, const avl_tree &R) {
    node_t *n = merge(L->root_, R->root_);
    return avl_tree(n);
  }
  std::pair<avl_tree, avl_tree> split(uint32 position) {
    std::pair<node_t *, node_t *> n = split(root_, position);
    return {avl_tree(n.first), avl_tree(n.second)};
  }
  avl_tree insert(uint32 position, Monoid data) {
    data_ = make(&nil, &nil, data);
    node_t *n = insert_(root_, position);
    return avl_tree(n);
  }
  avl_tree erase(uint32 position) { return avl_tree(erase_(root_, position)); }
  static avl_tree singlton(Monoid data) {
    return avl_tree(make(&nil, &nil, data));
  }
  Monoid range(uint32 begin, uint32 end) {
    if (begin >= end)
      return Monoid();
    node_t *n = root_;
    while (1) {
      if (n->left->size >= begin) {
        if (n->left->size < end) {
          return (more_than(n->left, begin) + n->value) +
                 less_than(n->right, end - n->left->size - 1);
        }
        n = n->left;
      } else {
        begin -= n->left->size + 1;
        end -= n->left->size + 1;
        n = n->right;
      }
    }
  }
  uint32 size(void) { return root_->size; }
  void show() {
    show(root_);
    std::cout << "\\n";
  }
};
template <typename Monoid>
typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::garbage = nullptr;
template <typename Monoid>
typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::data_ = nullptr;
template <typename Monoid>
typename avl_tree<Monoid>::node_t avl_tree<Monoid>::nil = {
    &avl_tree<Monoid>::nil,
    &avl_tree<Monoid>::nil,
    Monoid(),
    Monoid(),
    0,
    0,
    100};
struct ADD {
  int64 e;
  ADD(int64 t = 0) { e = t; }
  ADD operator*(const ADD &other) { return ADD(e + other.e); }
};

struct SUM {
  int64 e;
  int64 s;
  SUM(int64 x = 0, int64 y = 1) {
    e = x;
    s = y;
  }
  void set() {
    e = 0;
    s = 1;
  }
  void reverse(void) {}
  SUM operator+(const SUM &other) { return SUM(e + other.e, s + other.s); };
  SUM operator*(const ADD &other) { return SUM(e + (s * other.e), s); }
};

int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  avl_tree<SUM> T;
  uint32 n, q;
  std::cin >> n >> q;
  for (uint32 i = 0; i < n; ++i) {
    T = T.insert(0, SUM());
  }
  uint32 c, x, y;
  while (q--) {
    std::cin >> c >> x >> y;
    if (c) {
      std::cout << T.range(x - 1, y).e << "\\n";
    } else {
      // T.show();
      avl_tree<SUM> V = T.erase(x - 1);
      // V.show();
      T = V.insert(x - 1, T.access(x - 1) + SUM(y));
    }
    // T.show();
  }
  return 0;
}