Problem p02599 (C++)

Buggy submission (status: Time Limit Exceeded):
#pragma GCC optimize("O3")
// #pragma GCC target ("avx")
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...)                                                           \
  do {                                                                         \
  } while (0)
#endif
#include <cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define EACH(i, c)                                                             \
  for (__typeof((c).begin()) i = (c).begin(), i##_end = (c).end();             \
       i != i##_end; ++i)

template <class T> inline void amin(T &x, const T &y) {
  if (y < x)
    x = y;
}
template <class T> inline void amax(T &x, const T &y) {
  if (x < y)
    x = y;
}
template <class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\n');
}

int N, Q;

struct Query {
  int l, r, i;

  bool operator<(const Query &o) const { return r < o.r; }
};

const int MAXN = 500011;
const int MAGIC = 300;
const int SIZE = MAXN / MAGIC;
vector<Query> B[SIZE], P;

int C[MAXN];

int cnt;
int mem[MAXN];
int ans[MAXN];

void MAIN() {
  scanf("%d%d", &N, &Q);
  REP(i, N) scanf("%d", C + i);
  REP(i, Q) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    if (l / MAGIC == r / MAGIC) {
      P.push_back((Query){l, r, i});
    } else {
      B[l / MAGIC].push_back((Query){l, r, i});
    }
  }

  REP(k, SIZE) if (B[k].size()) {
    int sep = min(N, k * MAGIC + MAGIC);
    int R = sep;
    sort(B[k].begin(), B[k].end());

    cnt = 0;
    memset(mem, 0, sizeof mem);

    EACH(e, B[k]) {
      while (R < N && R < e->r) {
        if (mem[C[R]] == 0)
          cnt++;
        mem[C[R]]++;
        R++;
      }

      for (int i = e->l; i < sep; i++) {
        if (mem[C[i]] == 0)
          cnt++;
        mem[C[i]]++;
      }

      ans[e->i] = cnt;

      for (int i = e->l; i < sep; i++) {
        mem[C[i]]--;
        if (mem[C[i]] == 0)
          cnt--;
      }
    }
  }

  cnt = 0;
  memset(mem, 0, sizeof mem);

  EACH(e, P) {
    for (int i = e->l; i < e->r; i++) {
      if (mem[C[i]] == 0)
        cnt++;
      mem[C[i]]++;
    }

    ans[e->i] = cnt;

    for (int i = e->l; i < e->r; i++) {
      mem[C[i]]--;
      if (mem[C[i]] == 0)
        cnt--;
    }
  }

  REP(i, Q) printf("%d\n", ans[i]);
}

int main() {
  int TC = 1;
  //    scanf("%d", &TC);
  REP(tc, TC) MAIN();
  return 0;
}


Fixed submission:
#pragma GCC optimize("O3")
// #pragma GCC target ("avx")
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...)                                                           \
  do {                                                                         \
  } while (0)
#endif
#include <cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define EACH(i, c)                                                             \
  for (__typeof((c).begin()) i = (c).begin(), i##_end = (c).end();             \
       i != i##_end; ++i)

template <class T> inline void amin(T &x, const T &y) {
  if (y < x)
    x = y;
}
template <class T> inline void amax(T &x, const T &y) {
  if (x < y)
    x = y;
}
template <class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\n');
}

int N, Q;

struct Query {
  int l, r, i;

  bool operator<(const Query &o) const { return r < o.r; }
};

const int MAXN = 500011;
const int MAGIC = 700;
const int SIZE = MAXN / MAGIC;
vector<Query> B[SIZE], P;

int C[MAXN];

int cnt;
int mem[MAXN];
int ans[MAXN];

void MAIN() {
  scanf("%d%d", &N, &Q);
  REP(i, N) scanf("%d", C + i);
  REP(i, Q) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    if (l / MAGIC == r / MAGIC) {
      P.push_back((Query){l, r, i});
    } else {
      B[l / MAGIC].push_back((Query){l, r, i});
    }
  }

  REP(k, SIZE) if (B[k].size()) {
    int sep = min(N, k * MAGIC + MAGIC);
    int R = sep;
    sort(B[k].begin(), B[k].end());

    cnt = 0;
    memset(mem, 0, sizeof mem);

    EACH(e, B[k]) {
      while (R < N && R < e->r) {
        if (mem[C[R]] == 0)
          cnt++;
        mem[C[R]]++;
        R++;
      }

      for (int i = e->l; i < sep; i++) {
        if (mem[C[i]] == 0)
          cnt++;
        mem[C[i]]++;
      }

      ans[e->i] = cnt;

      for (int i = e->l; i < sep; i++) {
        mem[C[i]]--;
        if (mem[C[i]] == 0)
          cnt--;
      }
    }
  }

  cnt = 0;
  memset(mem, 0, sizeof mem);

  EACH(e, P) {
    for (int i = e->l; i < e->r; i++) {
      if (mem[C[i]] == 0)
        cnt++;
      mem[C[i]]++;
    }

    ans[e->i] = cnt;

    for (int i = e->l; i < e->r; i++) {
      mem[C[i]]--;
      if (mem[C[i]] == 0)
        cnt--;
    }
  }

  REP(i, Q) printf("%d\n", ans[i]);
}

int main() {
  int TC = 1;
  //    scanf("%d", &TC);
  REP(tc, TC) MAIN();
  return 0;
}