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

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

void solve(std::istream &in, std::ostream &out);

int main() {
#ifdef LOCAL
  freopen("../IO/f.in", "r", stdin);
//  freopen("../IO/f.out", "w", stdout);
#else
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);
#endif
  solve(std::cin, std::cout);
  return 0;
}

const int MAX = 500000 + 25;

struct Query {
  int l, r, idx;
};

bool cmp(Query x, Query y) { return x.r < y.r; }

void update(int idx, int val, int bit[], int n) {
  for (; idx <= n; idx += idx & -idx)
    bit[idx] += val;
}

int query(int idx, int bit[], int n) {
  int sum = 0;
  for (; idx > 0; idx -= idx & -idx)
    sum += bit[idx];
  return sum;
}

void answeringQueries(int arr[], int n, Query queries[], int q) {
  // initialising bit array
  int bit[n + 1];
  memset(bit, 0, sizeof(bit));

  // holds the rightmost index of any number
  // as numbers of a[i] are less than or equal to 10^6
  int last_visit[MAX];
  memset(last_visit, -1, sizeof(last_visit));

  // answer for each query
  int ans[q];
  int query_counter = 0;
  for (int i = 0; i < n; i++) {
    // If last visit is not -1 update -1 at the
    // idx equal to last_visit[arr[i]]
    if (last_visit[arr[i]] != -1)
      update(last_visit[arr[i]] + 1, -1, bit, n);

    // Setting last_visit[arr[i]] as i and updating
    // the bit array accordingly
    last_visit[arr[i]] = i;
    update(i + 1, 1, bit, n);

    // If i is equal to r of any query  store answer
    // for that query in ans[]
    while (query_counter < q && queries[query_counter].r == i) {
      ans[queries[query_counter].idx] =
          query(queries[query_counter].r + 1, bit, n) -
          query(queries[query_counter].l, bit, n);
      query_counter++;
    }
  }

  // print answer for each query
  for (int i = 0; i < q; i++)
    cout << ans[i] << endl;
}

int a[MAX];
Query queries[MAX];
void solve(std::istream &in, std::ostream &out) {
  int n, m;
  in >> n >> m;
  for (int i = 0; i < n; ++i) {
    in >> a[i];
  }
  for (int i = 0; i < m; ++i) {
    in >> queries[i].l >> queries[i].r;
    --queries[i].l;
    --queries[i].r;
    queries[i].idx = i;
  }
  sort(queries, queries + m, cmp);
  answeringQueries(a, n, queries, m);
}

Error: TLE

Fixed submission:

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

void solve(std::istream &in, std::ostream &out);

int main() {
#ifdef LOCAL
  freopen("../IO/f.in", "r", stdin);
//  freopen("../IO/f.out", "w", stdout);
#else
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);
#endif
  solve(std::cin, std::cout);
  return 0;
}

const int MAXN = 540005;
const int MAXM = 500005;
int N, M;
int A[MAXN], BL[MAXN], ID[MAXN], VAL[MAXN], ANS[MAXM];
int d[MAXN], l[MAXN], r[MAXN];
bool VIS[MAXN];

struct query {
  int id, l, r;
  bool operator<(const query &rhs) {
    return (BL[l] == BL[rhs.l]) ? (r < rhs.r) : (BL[l] < BL[rhs.l]);
  }
} Q[MAXM];

void check(int x, int &res) {
  // If (x) occurs twice, then don't consider it's value
  if ((VIS[x]) and (--VAL[A[x]] == 0))
    res--;
  else if ((!VIS[x]) and (VAL[A[x]]++ == 0))
    res++;
  VIS[x] ^= 1;
}

void compute() {

  // Perform standard Mo's Algorithm
  int curL = Q[0].l, curR = Q[0].l - 1, res = 0;
  for (int i = 0; i < M; i++) {
    while (curL < Q[i].l)
      check(curL++, res);
    while (curL > Q[i].l)
      check(--curL, res);
    while (curR < Q[i].r)
      check(++curR, res);
    while (curR > Q[i].r)
      check(curR--, res);
    ANS[Q[i].id] = res;
  }

  for (int i = 0; i < M; i++)
    cout << ANS[i] << '\\n';
}

void solve(std::istream &in, std::ostream &out) {
  in >> N >> M;
  for (int i = 1; i <= N; ++i) {
    in >> A[i];
  }
  int size = sqrt(N);

  for (int i = 1; i <= N; i++)
    BL[i] = (i - 1) / size + 1;
  for (int i = 0, u, v; i < M; i++) {
    in >> u >> v;
    Q[i].l = u, Q[i].r = v;
    Q[i].id = i;
  }
  sort(Q, Q + M);
  compute();
}