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

#include <algorithm>
#include <array>
#include <bitset>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdint.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldouble = long double;

// BDD,ZDD,kdtree, bdtree,bicalc, bolonoy, doloney, tree,
// chinesemod,segmenttree,daikusutora, saidairyuu, 2bugurahu, heirokenshutu,
// topologicalsort, kyourenketuseibun

#define PRI(s) cout << s << endl
#define PRIY PRI("Yes")
#define PRIN PRI("No")

template <typename T> class BIT {
public:
  int N;
  vector<T> seg;
  BIT(int N) : N(N) {
    seg.resize(N + 1);
    for (int i = 0; i < N + 1; ++i)
      seg[i] = 0;
  }

  // i番目にxを加算
  void add(int i, T x) {
    ++i;
    while (i <= N) {
      seg[i] += x;
      i += i & (-i);
    }
  }

  //[0,i)の和
  T cumulative(int i) {
    T s = 0;
    while (i > 0) {
      s += seg[i];
      i -= i & (-i);
    }
    return s;
  }

  //[a,b)の和
  T sum(int a, int b) { return cumulative(b) - cumulative(a); }

  // i番目の要素
  T elem(int i) { return sum(i, i + 1); }

  // i番目に代入
  void assign(int i, T x) {
    add(i, -elem(i));
    add(i, x);
  }
};

template <typename A> using P = pair<A, A>;

int N, Q;
vector<int> color;
vector<int> color_cnt;
vector<vector<int>> color_list;
vector<pair<P<int>, int>> query;
vector<int> ans;

int main() {
  cin >> N >> Q;
  color.resize(N);
  color_cnt.resize(N);
  color_list.resize(N);
  ans.resize(Q);
  query.resize(Q);
  for (int i = 0; i < N; ++i) {
    int c;
    cin >> c;
    --c;
    color[i] = c;
    color_cnt[i] = 0;
    color_list[c].push_back(i);
  }
  for (int i = 0; i < Q; ++i) {
    int l, r;
    cin >> l >> r;
    --l;
    --r;
    query[i] = pair<P<int>, int>(P<int>(l, r), i);
  }
  sort(query.begin(), query.end(),
       [](pair<P<int>, int> a, pair<P<int>, int> b) {
         if (a.first.first == b.first.first)
           return a.first.second < b.first.second;
         return a.first.first < b.first.first;
       });
  BIT<int> t(N);
  for (vector<int> &v : color_list) {
    if (v.empty())
      continue;
    t.assign(v[0], 1);
  }
  int qc = 0;
  for (int i = 0; i < N; ++i) {
    for (; qc < query.size() && query[qc].first.first == i; ++qc) {
      ans[query[qc].second] =
          t.sum(query[qc].first.first, query[qc].first.second + 1);
    }
    if (i == N - 1)
      break;
    int cur_color = color[i];
    color_cnt[cur_color]++;
    if (color_cnt[cur_color] >= color_list[cur_color].size())
      continue;
    t.assign(color_list[cur_color][color_cnt[cur_color]], 1);
  }
  for (int i = 0; i < Q; ++i)
    PRI(ans[i]);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdint.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldouble = long double;

// BDD,ZDD,kdtree, bdtree,bicalc, bolonoy,
// doloney,chinesemod,segmenttree,daikusutora, saidairyuu, 2bugurahu,
// heirokenshutu, topologicalsort, kyourenketuseibun

struct pop_buf {
  vector<int> buf;
  pop_buf() : buf(65536) {
    for (int i = 0; i < 65536; ++i) {
      buf[i] = 0;
      for (int j = 0; j < 16; ++j)
        if ((i & (1 << j)) > 0)
          ++buf[i];
    }
  }
};

pop_buf pbuf;

int popcnt(uint64_t b, const pop_buf &buf) {
  uint16_t *p = reinterpret_cast<uint16_t *>(&b);
  int res = 0;
  res += buf.buf[p[0]];
  res += buf.buf[p[1]];
  res += buf.buf[p[2]];
  res += buf.buf[p[3]];
  return res;
}

struct flagtree_leaf {
  uint64_t b;
  int64_t s;
};

using flagtree = list<flagtree_leaf>;

int flag_cnt(const flagtree &t) {
  int res = 0;
  for (const flagtree_leaf &l : t)
    res += popcnt(l.b, pbuf);
  return res;
}

void flag_or(const flagtree &source, flagtree &target) {

  auto its = source.begin();
  auto itt = target.begin();
  if (itt == target.end()) {
    target = source;
    return;
  }
  while (its != source.end()) {
    while (itt != target.end()) {
      if (itt->s == its->s)
        break;
      auto ittnext = next(itt);
      if (ittnext != target.end() && ittnext->s > its->s)
        break;
      ++itt;
    }
    if (itt != target.end() && itt->s == its->s)
      itt->b |= its->b;
    else
      target.insert(itt, *its);
    ++its;
  }
}

template <typename T> struct binseg_tree_node {
  T v;
  int s;
  int e;
  binseg_tree_node<T> *p;
  binseg_tree_node<T> *c1;
  binseg_tree_node<T> *c2;
};

template <typename T> class binseg_tree {
public:
  vector<binseg_tree_node<T>> t;
  binseg_tree_node<T> *create_node(int s, int e, binseg_tree_node<T> *p) {
    t.emplace_back();
    int i = t.size() - 1;
    t[i].s = s;
    t[i].e = e;
    t[i].p = p;

    if (s == e) {
      t[i].c1 = nullptr;
      t[i].c2 = nullptr;
    } else {
      t[i].c1 = create_node(s, (e + s) / 2, &t[i]);
      t[i].c2 = create_node(((e + s) / 2) + 1, e, &t[i]);
    }
    return &t[i];
  }
  binseg_tree(int range_pow2) {
    unsigned int size = 1 << range_pow2;
    t.reserve(size * 2 - 1);
    create_node(0, size - 1, nullptr);
  }
};

using ftree = binseg_tree<flagtree>;

vector<int> color;

void construct(ftree &t) {
  reverse_iterator<decltype(t.t)::iterator> first(t.t.end());
  reverse_iterator<decltype(t.t)::iterator> last(t.t.begin());
  for_each(first, last, [](binseg_tree_node<flagtree> &t) {
    if (t.s == t.e) {
      if (t.s < color.size())
        t.v.emplace_back(flagtree_leaf{(uint64_t)(1ull << (color[t.s] % 64)),
                                       (int64_t)(color[t.s] / 64)});
      else
        t.v.emplace_back(flagtree_leaf{0, 0});
    } else {
      t.v = t.c1->v;
      flag_or(t.c2->v, t.v);
    }
  });
}

void query_sub(binseg_tree_node<flagtree> &n, flagtree &f, int s, int e) {
  if (s == n.s && e == n.e) {
    flag_or(n.v, f);
    return;
  } else {
    if (s <= n.c1->e)
      query_sub(*n.c1, f, s, min(n.c1->e, e));
    if (n.c2->s <= e)
      query_sub(*n.c2, f, max(n.c2->s, s), e);
  }
}

int query(ftree &t, int s, int e) {
  flagtree buf;
  query_sub(t.t.front(), buf, s, e);
  return flag_cnt(buf);
}

int msb(uint64_t b, const pop_buf &buf) {
  b |= b >> 1;
  b |= b >> 2;
  b |= b >> 4;
  b |= b >> 8;
  b |= b >> 16;
  b |= b >> 32;
  return popcnt(b, buf);
}
int main() {

  int N, Q;
  cin >> N >> Q;
  color.resize(N);
  for (int i = 0; i < N; ++i) {
    cin >> color[i];
    --color[i];
  }
  pop_buf pb;
  ftree t(msb(N, pb));
  construct(t);

  for (int i = 0; i < Q; ++i) {
    int l, r;
    cin >> l >> r;
    l--;
    r--;
    if (N == 1)
      cout << 1 << endl;
    else {
      cout << query(t, l, r) << endl;
    }
  }

  return 0;
}