Problem p02351 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <climits>
#include <fstream>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>

typedef int Data;
typedef long long LongData;

using namespace std;

struct Node {
  Data data;
  int priority;
  size_t weight;
  LongData sum;
  LongData addition;
  Node *left;
  Node *right;

  Node() {
    weight = 1;
    left = nullptr;
    right = nullptr;
  }

  Node(Data data, int priority = rand()) {
    this->data = data;
    this->priority = priority;
    this->weight = 1;
    this->sum = data;
    this->addition = 0;
    left = nullptr;
    right = nullptr;
  }
};

class Treap {
private:
  Node *root;

  void split(Node *current, size_t implicitKey, Node *&left, Node *&right) {
    push(current);

    if (current == nullptr) {
      left = right = nullptr;
      return;
    }

    size_t currentIndex =
        (current->left != nullptr ? current->left->weight : 0) + 1;

    if (currentIndex < implicitKey) {
      split(current->right, implicitKey - currentIndex, current->right, right);
      left = current;
    }

    else {
      split(current->left, implicitKey, left, current->left);
      right = current;
    }

    upadte(current);
  }

  Node *merge(Node *&left, Node *&right) {
    push(left);
    push(right);

    if (left == nullptr)
      return right;

    if (right == nullptr)
      return left;

    if (left->priority > right->priority) {
      left->right = merge(left->right, right);
      upadte(left);
      return left;
    }

    else {
      right->left = merge(left, right->left);
      upadte(right);
      return right;
    }
  }

  void upadte(Node *node, bool doPushing = true) {
    // push(node);
    push(node->left);
    push(node->right);

    if (node == nullptr)
      return;

    node->weight = 1 + (node->left == nullptr ? 0 : node->left->weight) +
                   (node->right == nullptr ? 0 : node->right->weight);
    // node->sum = node->data + (node->left == nullptr ? 0 : node->left->sum +
    // node->left->weight*node->left->addition) + (node->right == nullptr ? 0 :
    // node->right->sum + node->right->weight*node->right->addition);
    node->sum = node->data + (node->left == nullptr ? 0 : node->left->sum) +
                (node->right == nullptr ? 0 : node->right->sum);
  }

  void push(Node *node) {
    if (node == nullptr)
      return;

    if (node->left != nullptr)
      node->left->addition += node->addition;

    if (node->right != nullptr)
      node->right->addition += node->addition;

    node->data += node->addition;
    node->sum += node->addition * node->weight;
    node->addition = 0;
  }

  void updateSubTree(Node *node = nullptr) {
    if (node == nullptr)
      node = root;

    if (node->left != nullptr)
      upadte(node->left);

    if (node->right != nullptr)
      upadte(node->right);

    upadte(node);
  }

public:
  // Constructors and Destructors:

  Treap(Node *root = nullptr) { this->root = root; }

  Treap(Data data, int priority) { root = new Node(data, priority); }

  ~Treap() { clear(); }

  void clear() {
    queue<Node *> que;
    que.push(root);

    while (!que.empty()) {
      Node *current = que.front();
      que.pop();

      if (current == nullptr)
        continue;

      que.push(current->left);
      que.push(current->right);

      delete current;
    }
  }

  // Getters:

  void getArray(vector<Data> &array, Node *node = nullptr) const {
    if (node == nullptr) {
      array.clear();
      node = root;
    }

    if (root == nullptr)
      return;

    if (node->left != nullptr)
      getArray(array, node->left);

    array.push_back(node->data);

    if (node->right != nullptr)
      getArray(array, node->right);
  }

  ostream &print(ostream &os) const {
    queue<Node *> que;
    que.push(root);

    while (!que.empty()) {
      Node *current = que.front();
      que.pop();

      if (current == nullptr)
        continue;

      os << current->data << " (sum: " << current->sum
         << ", addition: " << current->addition << "): left – ";

      if (current->left == nullptr)
        cout << "x";

      else
        cout << current->left->data;

      cout << " right – ";

      if (current->right == nullptr)
        cout << "x" << endl;

      else
        cout << current->right->data << endl;

      que.push(current->left);
      que.push(current->right);
    }

    return os;
  }

  size_t size() {
    updateSubTree(root);
    return root->weight;
  }

  // Main methods:

  pair<Treap, Treap> Split(size_t pos) {
    Node *left, *right;
    split(root, pos, left, right);
    return make_pair(Treap(left), Treap(right));
  }

  Treap Merge(Treap left, Treap right) {
    Node *merged = merge(left.root, right.root);
    return Treap(merged);
  }

  void insert(Data data, size_t pos = INT_MAX - 1, int priority = rand()) {
    Node *left, *right;
    split(root, pos + 1, left, right);
    Node *insertion = new Node(data, priority);
    left = merge(left, insertion);
    root = merge(left, right);
  }

  void remove(size_t pos) {
    Node *left, *right;
    split(root, pos + 1, left, right);
    Node *deletion;
    split(right, 2, deletion, right);
    root = merge(left, right);
    delete deletion;
  }

  // Subsegments' methods:

  void moveSubsegmentToFront(size_t l, size_t r) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    left = merge(middle, left);
    root = merge(left, right);
  }

  void moveSubsegmentToBack(size_t l, size_t r) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    right = merge(right, middle);
    root = merge(left, right);
  }

  LongData getSumOnSubsegment(size_t l, size_t r) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    LongData sum = middle->sum;
    left = merge(left, middle);
    root = merge(left, right);
    return sum;
  }

  void addOnSubsegment(size_t l, size_t r, LongData addition) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    middle->addition += addition;
    left = merge(left, middle);
    root = merge(left, right);
  }
};

ostream &operator<<(ostream &os, const vector<int> &vec) {
  for (int el : vec)
    cout << el << " ";

  return os;
}

ostream &operator<<(ostream &os, const Treap &treap) {
  vector<Data> array;
  treap.getArray(array);
  os << array << endl;
  return treap.print(os);
  return os;
}

int main() {
  Treap treap;

  size_t n;
  cin >> n;

  for (int i = 0; i < n; i++)
    treap.insert(0);

  // cout << endl << treap << endl;

  size_t q;
  cin >> q;

  while (q--) {
    int type;
    cin >> type;

    if (type == 1) {
      size_t l, r;
      cin >> l >> r;
      cout << treap.getSumOnSubsegment(l, r) << endl;
    }

    /*else if (type == 2) {
            Data el;
            int pos;
            cin >> pos >> el;
            treap.insert(el, pos);
    }

    else if (type == 3) {
            size_t pos;
            cin >> pos;
            treap.remove(pos);
    }*/

    else if (type == 0) {
      size_t l, r;
      LongData addition;
      cin >> l >> r >> addition;
      treap.addOnSubsegment(l, r, addition);
    }

    // cout << treap << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <fstream>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>

typedef int Data;
typedef long long LongData;

using namespace std;

struct Node {
  Data data;
  int priority;
  size_t weight;
  LongData sum;
  LongData addition;
  Node *left;
  Node *right;

  Node() {
    weight = 1;
    left = nullptr;
    right = nullptr;
  }

  Node(Data data, int priority = rand()) {
    this->data = data;
    this->priority = priority;
    this->weight = 1;
    this->sum = data;
    this->addition = 0;
    left = nullptr;
    right = nullptr;
  }
};

class Treap {
private:
  Node *root;

  void split(Node *current, size_t implicitKey, Node *&left, Node *&right) {
    push(current);

    if (current == nullptr) {
      left = right = nullptr;
      return;
    }

    size_t currentIndex =
        (current->left != nullptr ? current->left->weight : 0) + 1;

    if (currentIndex < implicitKey) {
      split(current->right, implicitKey - currentIndex, current->right, right);
      left = current;
    }

    else {
      split(current->left, implicitKey, left, current->left);
      right = current;
    }

    update(current);
  }

  Node *merge(Node *&left, Node *&right) {
    push(left);
    push(right);

    if (left == nullptr)
      return right;

    if (right == nullptr)
      return left;

    if (left->priority > right->priority) {
      left->right = merge(left->right, right);
      update(left);
      return left;
    }

    else {
      right->left = merge(left, right->left);
      update(right);
      return right;
    }
  }

  void update(Node *node) {
    if (node == nullptr)
      return;

    node->weight = 1 + (node->left == nullptr ? 0 : node->left->weight) +
                   (node->right == nullptr ? 0 : node->right->weight);

    if (node->left != nullptr)
      push(node->left);

    if (node->right != nullptr)
      push(node->right);

    node->sum = node->data + (node->left == nullptr ? 0 : node->left->sum) +
                (node->right == nullptr ? 0 : node->right->sum);
  }

  void push(Node *node) {
    update(node);

    if (node == nullptr)
      return;

    if (node->left != nullptr)
      node->left->addition += node->addition;

    if (node->right != nullptr)
      node->right->addition += node->addition;

    if (node->left == nullptr && node->right == nullptr)

      node->sum += node->weight * node->addition;
    node->data += node->addition;
    node->addition = 0;
  }

  void updateSubTree(Node *node = nullptr) {
    if (node == nullptr)
      node = root;

    if (node->left != nullptr)
      update(node->left);

    if (node->right != nullptr)
      update(node->right);

    update(node);
  }

public:
  // Constructors and Destructors:

  Treap(Node *root = nullptr) { this->root = root; }

  Treap(Data data, int priority) { root = new Node(data, priority); }

  ~Treap() { clear(); }

  void clear() {
    queue<Node *> que;
    que.push(root);

    while (!que.empty()) {
      Node *current = que.front();
      que.pop();

      if (current == nullptr)
        continue;

      que.push(current->left);
      que.push(current->right);

      delete current;
    }
  }

  // Getters:

  void getArray(vector<Data> &array, Node *node = nullptr) const {
    if (node == nullptr) {
      array.clear();
      node = root;
    }

    if (root == nullptr)
      return;

    if (node->left != nullptr)
      getArray(array, node->left);

    array.push_back(node->data);

    if (node->right != nullptr)
      getArray(array, node->right);
  }

  ostream &print(ostream &os) const {
    queue<Node *> que;
    que.push(root);

    while (!que.empty()) {
      Node *current = que.front();
      que.pop();

      if (current == nullptr)
        continue;

      os << current->data << " (sum: " << current->sum
         << ", addition: " << current->addition << "): left – ";

      if (current->left == nullptr)
        cout << "x";

      else
        cout << current->left->data;

      cout << " right – ";

      if (current->right == nullptr)
        cout << "x" << endl;

      else
        cout << current->right->data << endl;

      que.push(current->left);
      que.push(current->right);
    }

    return os;
  }

  size_t size() {
    updateSubTree(root);
    return root->weight;
  }

  // Main methods:

  pair<Treap, Treap> Split(size_t pos) {
    Node *left, *right;
    split(root, pos, left, right);
    return make_pair(Treap(left), Treap(right));
  }

  Treap Merge(Treap left, Treap right) {
    Node *merged = merge(left.root, right.root);
    return Treap(merged);
  }

  void insert(Data data, size_t pos = INT_MAX - 1, int priority = rand()) {
    Node *left, *right;
    split(root, pos + 1, left, right);
    Node *insertion = new Node(data, priority);
    left = merge(left, insertion);
    root = merge(left, right);
  }

  void remove(size_t pos) {
    Node *left, *right;
    split(root, pos + 1, left, right);
    Node *deletion;
    split(right, 2, deletion, right);
    root = merge(left, right);
    delete deletion;
  }

  // Subsegments' methods:

  void moveSubsegmentToFront(size_t l, size_t r) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    left = merge(middle, left);
    root = merge(left, right);
  }

  void moveSubsegmentToBack(size_t l, size_t r) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    right = merge(right, middle);
    root = merge(left, right);
  }

  LongData getSumOnSubsegment(size_t l, size_t r) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    LongData sum = middle->sum;
    left = merge(left, middle);
    root = merge(left, right);
    return sum;
  }

  void addOnSubsegment(size_t l, size_t r, LongData addition) {
    Node *left, *middle, *right;
    split(root, l, left, right);
    split(right, r - l + 2, middle, right);
    middle->addition += addition;
    left = merge(left, middle);
    root = merge(left, right);
  }
};

ostream &operator<<(ostream &os, const vector<int> &vec) {
  for (int el : vec)
    cout << el << " ";

  return os;
}

ostream &operator<<(ostream &os, const Treap &treap) {
  vector<Data> array;
  treap.getArray(array);
  os << array << endl;
  return treap.print(os);
  return os;
}

int main() {
  Treap treap;

  size_t n;
  cin >> n;

  for (int i = 0; i < n; i++)
    treap.insert(0);

  // cout << endl << treap << endl;

  size_t q;
  cin >> q;

  while (q--) {
    int type;
    cin >> type;

    if (type == 1) {
      size_t l, r;
      cin >> l >> r;
      cout << treap.getSumOnSubsegment(l, r) << endl;
    }

    /*else if (type == 2) {
            Data el;
            int pos;
            cin >> pos >> el;
            treap.insert(el, pos);
    }

    else if (type == 3) {
            size_t pos;
            cin >> pos;
            treap.remove(pos);
    }*/

    else if (type == 0) {
      size_t l, r;
      LongData addition;
      cin >> l >> r >> addition;
      treap.addOnSubsegment(l, r, addition);
    }

    // cout << treap << endl;
  }

  return 0;
}