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

#include "bits/stdc++.h"
#include <boost/dynamic_bitset.hpp>
#include <boost/multi_array.hpp>
#include <boost/optional.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
namespace adaptor = boost::adaptors;
using index_t = std::size_t;

namespace lib {
using graph_t = std::vector<std::set<index_t>>;
template <class T> using weighted_graph_t = std::vector<std::map<index_t, T>>;

struct max_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::max(lhs, rhs);
  }
};
struct min_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::min(lhs, rhs);
  }
};

constexpr max_t max;
constexpr min_t min;

template <class T> auto order_by(T func) {
  return [=](auto &&lhs, auto &&rhs) { return func(lhs) < func(rhs); };
}

template <class T> constexpr auto max_v = std::numeric_limits<T>::max();
template <class T> constexpr auto min_v = std::numeric_limits<T>::min();

template <class T>
using p_queue = std::priority_queue<T, std::vector<T>, std::greater<>>;
} // namespace lib

template <class T, class Op = std::plus<>> class binary_indexed_tree {
  std::vector<T> vec;
  std::size_t sz;
  Op op;

public:
  binary_indexed_tree(std::size_t size, Op f = Op())
      : vec(size), sz(size), op(f) {}
  void add(int i, T const &val) {
    ++i;
    while (i <= sz) {
      vec[i - 1] = op(vec[i - 1], val);
      i += i & -i;
    }
  }
  auto get(int i) const {
    ++i;
    T ret{};
    while (i != 0) {
      ret += vec[i - 1];
      i -= i & -i;
    }
    return ret;
  }
};

void Main() {
  int N, Q;
  std::cin >> N >> Q;
  std::vector<int> vec(N);
  for (auto &v : vec) {
    std::cin >> v;
  }
  std::vector<std::tuple<int, int, int>> query(Q);
  for (auto i : boost::irange(Q)) {
    int x, y;
    std::cin >> x >> y;
    query[i] = std::make_tuple(x - 1, y, i);
  }
  std::vector<int> answer(Q), appear(N, -1);
  binary_indexed_tree<int> bit(N + 1);
  boost::sort(query, lib::order_by([](auto &&v) { return std::get<1>(v); }));
  int last = 0;
  for (auto [x, y, i] : query) {
    for (; last < y; ++last) {
      bit.add(last + 1, 1);
      if (appear[vec[last]] != -1) {
        bit.add(appear[vec[last]], -1);
      }
      appear[vec[last]] = last + 1;
    }
    answer[i] = bit.get(y) - bit.get(x);
  }
  for (auto &&v : answer) {
    std::cout << v << std::endl;
  }
}

int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout << std::fixed << std::setprecision(15);
  Main();
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <boost/dynamic_bitset.hpp>
#include <boost/multi_array.hpp>
#include <boost/optional.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
namespace adaptor = boost::adaptors;
using index_t = std::size_t;

namespace lib {
using graph_t = std::vector<std::set<index_t>>;
template <class T> using weighted_graph_t = std::vector<std::map<index_t, T>>;

struct max_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::max(lhs, rhs);
  }
};
struct min_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::min(lhs, rhs);
  }
};

constexpr max_t max;
constexpr min_t min;

template <class T> auto order_by(T func) {
  return [=](auto &&lhs, auto &&rhs) { return func(lhs) < func(rhs); };
}

template <class T> constexpr auto max_v = std::numeric_limits<T>::max();
template <class T> constexpr auto min_v = std::numeric_limits<T>::min();

template <class T>
using p_queue = std::priority_queue<T, std::vector<T>, std::greater<>>;
} // namespace lib

std::size_t get_size(std::size_t s) {
  std::size_t ret = 1;
  while (ret < s) {
    ret <<= 1;
  }
  return ret;
}

void set_union(std::set<int> const &a, std::set<int> const &b,
               std::set<int> &c) {
  std::set_union(a.begin(), a.end(), b.begin(), b.end(),
                 std::inserter(c, c.end()));
}

void Main() {
  std::size_t N, Q;
  std::cin >> N >> Q;
  auto M = get_size(N);
  std::vector<std::set<int>> sets(2 * M);
  for (auto i : boost::irange(N)) {
    int v;
    std::cin >> v;
    sets[i + M].emplace(v);
  }
  N = M;
  for (auto s = N / 2; s > 0; s /= 2) {
    for (index_t i = 0; i < s; ++i) {
      set_union(sets[2 * (i + s)], sets[2 * (i + s) + 1], sets[i + s]);
    }
  }
  for (auto q : boost::irange(Q)) {
    std::size_t x, y;
    std::cin >> x >> y;
    --x;
    std::set<int> L, R;
    for (std::size_t a = x + N, b = y + N; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        L.insert(sets[a].begin(), sets[a].end());
        a++;
      }
      if (b & 1) {
        --b;
        R.insert(sets[b].begin(), sets[b].end());
      }
    }
    L.insert(R.begin(), R.end());
    std::cout << L.size() << std::endl;
  }
}

int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout << std::fixed << std::setprecision(15);
  Main();
}