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

#include <bits/stdc++.h>

using namespace std;

#define INF (1ll << 62)
#define pb push_back
#define ii pair<int, int>
#define OK (cerr << "OK" << endl)
#define debug(x) cerr << #x " = " << (x) << endl
#define ff first
#define ss second
// #define int long long
#define tt tuple<int, int, int>
#define endl '\\n'

class Persistent_Seg_Tree {
private:
  int n;

public:
  struct Node {
    int val;
    Node *left, *right;
    Node() {}
    Node(int v, Node *l, Node *r) : val(v), left(l), right(r) {}
  };

#define NEUTRAL_NODE Node(0, nullptr, nullptr);
  Node _NEUTRAL_NODE = Node(0, nullptr, nullptr);
  vector<Node *> version;

  int merge_nodes(const int x, const int y) { return x + y; }

  Node *pst_build(Node *node, const int l, const int r,
                  const vector<int> &arr) {
    node = new NEUTRAL_NODE;
    if (l == r) {
      node->val = arr[l];
      return node;
    }

    int mid = (l + r) / 2;
    node->left = pst_build(node->left, l, mid, arr);
    node->right = pst_build(node->right, mid + 1, r, arr);
    node->val = merge_nodes(node->left->val, node->right->val);
    return node;
  }

  Node *pst_build_empty(Node *node, const int l, const int r) {
    node = new NEUTRAL_NODE;
    if (l == r)
      return node;

    int mid = (l + r) / 2;
    node->left = pst_build_empty(node->left, l, mid);
    node->right = pst_build_empty(node->right, mid + 1, r);
    node->val = merge_nodes(node->left->val, node->right->val);
    return node;
  }

  Node *pst_update(Node *cur_tree, Node *prev_tree, const int l, const int r,
                   const int idx, const int v) {
    if (l > idx || r < idx) {
      if (cur_tree != nullptr)
        return cur_tree;
      return prev_tree;
    }

    if (cur_tree == nullptr)
      cur_tree = new Node(prev_tree->val, nullptr, nullptr);

    if (l == r) {
      cur_tree->val += v;
      return cur_tree;
    }

    int mid = (l + r) / 2;
    cur_tree->left =
        pst_update(cur_tree->left, prev_tree->left, l, mid, idx, v);
    cur_tree->right =
        pst_update(cur_tree->right, prev_tree->right, mid + 1, r, idx, v);
    cur_tree->val = merge_nodes(cur_tree->left->val, cur_tree->right->val);
    return cur_tree;
  }

  int pst_query(Node *node, const int l, const int r, const int i,
                const int j) {
    if (l > j || r < i)
      return _NEUTRAL_NODE.val;

    if (i <= l && r <= j)
      return node->val;

    int mid = (l + r) / 2;
    return merge_nodes(pst_query(node->left, l, mid, i, j),
                       pst_query(node->right, mid + 1, r, i, j));
  }

public:
  Persistent_Seg_Tree(const int n, const int number_of_versions) {
    this->n = n;
    version.resize(number_of_versions);
    this->version[0] = this->pst_build_empty(this->version[0], 0, this->n - 1);
  }

  Persistent_Seg_Tree(const int n, const int number_of_versions,
                      vector<int> &arr) {
    this->n = n;
    version.resize(number_of_versions);
    this->version[0] = this->pst_build(this->version[0], 0, this->n - 1, arr);
  }

  void update(const int cur_version, const int prev_version, const int idx,
              const int v) {
    this->version[cur_version] =
        this->pst_update(this->version[cur_version],
                         this->version[prev_version], 0, this->n - 1, idx, v);
  }

  int query(const int version, const int l, const int r) {
    assert(0 <= l);
    assert(l <= r);
    assert(r < this->n);
    return this->pst_query(this->version[version], 0, this->n - 1, l, r);
  }
};

signed main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n, q;

  cin >> n >> q;

  unordered_map<int, int> last;

  vector<int> arr(n + 2);

  Persistent_Seg_Tree pst(n + 2, n + 2, arr);

  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;

    if (last.count(x))
      pst.update(i, i - 1, last[x], -1);

    pst.update(i, i - 1, i, 1);

    last[x] = i;
  }

  while (q--) {
    int l, r;
    cin >> l >> r;

    int ans = pst.query(r, l, r);

    cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define INF (1ll << 62)
#define pb push_back
#define ii pair<int, int>
#define OK (cerr << "OK" << endl)
#define debug(x) cerr << #x " = " << (x) << endl
#define ff first
#define ss second
#define int long long
#define tt tuple<int, int, int>
#define endl '\\n'

class Persistent_Seg_Tree {
private:
  int n;

public:
  struct Node {
    int val;
    Node *left, *right;
    Node() {}
    Node(int v, Node *l, Node *r) : val(v), left(l), right(r) {}
  };

#define NEUTRAL_NODE Node(0, nullptr, nullptr);
  Node _NEUTRAL_NODE = Node(0, nullptr, nullptr);
  vector<Node *> version;

  int merge_nodes(const int x, const int y) { return x + y; }

  Node *pst_build(Node *node, const int l, const int r,
                  const vector<int> &arr) {
    node = new NEUTRAL_NODE;
    if (l == r) {
      node->val = arr[l];
      return node;
    }

    int mid = (l + r) / 2;
    node->left = pst_build(node->left, l, mid, arr);
    node->right = pst_build(node->right, mid + 1, r, arr);
    node->val = merge_nodes(node->left->val, node->right->val);
    return node;
  }

  Node *pst_build_empty(Node *node, const int l, const int r) {
    node = new NEUTRAL_NODE;
    if (l == r)
      return node;

    int mid = (l + r) / 2;
    node->left = pst_build_empty(node->left, l, mid);
    node->right = pst_build_empty(node->right, mid + 1, r);
    node->val = merge_nodes(node->left->val, node->right->val);
    return node;
  }

  Node *pst_update(Node *cur_tree, Node *prev_tree, const int l, const int r,
                   const int idx, const int v) {
    if (l > idx || r < idx) {
      if (cur_tree != nullptr)
        return cur_tree;
      return prev_tree;
    }

    if (cur_tree == nullptr)
      cur_tree = new Node(prev_tree->val, nullptr, nullptr);

    if (l == r) {
      cur_tree->val += v;
      return cur_tree;
    }

    int mid = (l + r) / 2;
    cur_tree->left =
        pst_update(cur_tree->left, prev_tree->left, l, mid, idx, v);
    cur_tree->right =
        pst_update(cur_tree->right, prev_tree->right, mid + 1, r, idx, v);
    cur_tree->val = merge_nodes(cur_tree->left->val, cur_tree->right->val);
    return cur_tree;
  }

  int pst_query(Node *node, const int l, const int r, const int i,
                const int j) {
    if (l > j || r < i)
      return _NEUTRAL_NODE.val;

    if (i <= l && r <= j)
      return node->val;

    int mid = (l + r) / 2;
    return merge_nodes(pst_query(node->left, l, mid, i, j),
                       pst_query(node->right, mid + 1, r, i, j));
  }

public:
  Persistent_Seg_Tree(const int n, const int number_of_versions) {
    this->n = n;
    version.resize(number_of_versions);
    this->version[0] = this->pst_build_empty(this->version[0], 0, this->n - 1);
  }

  Persistent_Seg_Tree(const int n, const int number_of_versions,
                      vector<int> &arr) {
    this->n = n;
    version.resize(number_of_versions);
    this->version[0] = this->pst_build(this->version[0], 0, this->n - 1, arr);
  }

  void update(const int cur_version, const int prev_version, const int idx,
              const int v) {
    this->version[cur_version] =
        this->pst_update(this->version[cur_version],
                         this->version[prev_version], 0, this->n - 1, idx, v);
  }

  int query(const int version, const int l, const int r) {
    assert(0 <= l);
    assert(l <= r);
    assert(r < this->n);
    return this->pst_query(this->version[version], 0, this->n - 1, l, r);
  }
};

signed main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n, q;

  cin >> n >> q;

  unordered_map<int, int> last;

  vector<int> arr(n + 2);

  Persistent_Seg_Tree pst(n + 2, n + 2, arr);

  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;

    if (last.count(x))
      pst.update(i, i - 1, last[x], -1);

    pst.update(i, i - 1, i, 1);

    last[x] = i;
  }

  while (q--) {
    int l, r;
    cin >> l >> r;

    int ans = pst.query(r, l, r);

    cout << ans << endl;
  }
}