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

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define endl "\\n"
#define IOS                                                                    \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

#define BLOCK 700 // Block Size

const int MAX = 5e5 + 5;

struct query {
  int l;
  int r;
  int index;
};

query Q[MAX];
int arr[MAX], ans[MAX]; // arr[] is 1 based indexed. Others are 0 based indexed.
int freq[MAX];
int ct = 0;

bool comp(query a, query b) {
  if (a.l / BLOCK != b.l / BLOCK)
    return a.l / BLOCK < b.l / BLOCK;
  // return a.r < b.r;
  return (a.l / BLOCK & 1) ? (a.r < b.r) : (a.r > b.r);
}

void add(int pos) {
  freq[arr[pos]] += 1;
  if (freq[arr[pos]] == 1)
    ct += 1;
}

void remove(int pos) {
  freq[arr[pos]] -= 1;
  if (freq[arr[pos]] == 0)
    ct -= 1;
}

int main() {
  IOS int t = 1;
  // cin >> t;
  while (t--) {
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
      cin >> arr[i];
    }

    for (int i = 0; i < q; i++) {
      cin >> Q[i].l >> Q[i].r;
      Q[i].index = i;
    }

    sort(Q, Q + q, comp); // Sorting all queries on the basis of 'L'. If 'L' is
                          // same, then sort on the basis of 'R'.

    int ML = 0, MR = -1; // ML = MO's Left pointer && MR = MO's Right pointer

    for (int i = 0; i < q; i++) {
      int L = Q[i].l;
      int R = Q[i].r;

      while (ML > L)
        ML--, add(ML);

      while (MR < R)
        MR++, add(MR);

      while (ML < L)
        remove(ML), ML++;

      while (MR > R)
        remove(MR), MR--;

      ans[Q[i].index] = ct; // store answer of each query in the ans[] array.
    }

    for (int i = 0; i < q; i++)
      cout << ans[i] << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define endl "\\n"
#define IOS                                                                    \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

#define BLOCK 555 // Block Size

const int MAX = 5e5 + 5;

struct query {
  int l;
  int r;
  int index;
};

query Q[MAX];
int arr[MAX], ans[MAX]; // arr[] is 1 based indexed. Others are 0 based indexed.
int freq[MAX];
int ct = 0;

bool comp(query a, query b) {
  if (a.l / BLOCK != b.l / BLOCK)
    return a.l / BLOCK < b.l / BLOCK;

  return a.r < b.r;
}

void add(int pos) {
  freq[arr[pos]] += 1;
  if (freq[arr[pos]] == 1)
    ct += 1;
}

void remove(int pos) {
  freq[arr[pos]] -= 1;
  if (freq[arr[pos]] == 0)
    ct -= 1;
}

int main() {
  IOS int t = 1;
  // cin >> t;
  while (t--) {
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
      cin >> arr[i];
    }

    for (int i = 0; i < q; i++) {
      cin >> Q[i].l >> Q[i].r;
      Q[i].index = i;
    }

    sort(Q, Q + q, comp); // Sorting all queries on the basis of 'L'. If 'L' is
                          // same, then sort on the basis of 'R'.

    int ML = 0, MR = -1; // ML = MO's Left pointer && MR = MO's Right pointer

    for (int i = 0; i < q; i++) {
      int L = Q[i].l;
      int R = Q[i].r;

      while (ML > L)
        ML--, add(ML);

      while (MR < R)
        MR++, add(MR);

      while (ML < L)
        remove(ML), ML++;

      while (MR > R)
        remove(MR), MR--;

      ans[Q[i].index] = ct; // store answer of each query in the ans[] array.
    }

    for (int i = 0; i < q; i++)
      cout << ans[i] << endl;
  }
  return 0;
}