kyopro-lib

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:warning: Range set query
(Mylib/Typical/range_set_query.cpp)

Operations

区間に含まれる要素の種類数を求めるクエリを処理する。

Requirements

Notes

Problems

References

Depends on

Code

#pragma once
#include <algorithm>
#include <tuple>
#include <vector>
#include "Mylib/DataStructure/FenwickTree/fenwick_tree_add.cpp"

namespace haar_lib {
  template <typename T>
  class range_set_query {
    std::vector<int> a_;
    std::vector<std::tuple<int, int, int>> qs_;
    int N_;

  public:
    range_set_query() {}
    range_set_query(std::vector<T> a) : N_(a.size()) {
      auto temp = a;
      std::sort(temp.begin(), temp.end());
      temp.erase(std::unique(temp.begin(), temp.end()), temp.end());

      for (auto x : a) {
        const int i = std::lower_bound(temp.begin(), temp.end(), x) - temp.begin();
        a_.push_back(i);
      }
    }

    void add(int l, int r) {  // [l, r)
      const int i = qs_.size();
      qs_.emplace_back(r, l, i);
    }

    auto solve() {
      std::sort(qs_.begin(), qs_.end());

      fenwick_tree_add<int> b(N_);

      const int Q = qs_.size();
      std::vector<int> last_index(N_, -1), ret(Q);

      int cur = 0;
      for (auto [r, l, i] : qs_) {
        while (cur < r) {
          if (last_index[a_[cur]] != -1) {
            b.update(last_index[a_[cur]], -1);
          }

          last_index[a_[cur]] = cur;
          b.update(last_index[a_[cur]], 1);

          ++cur;
        }

        ret[i] = b.fold(l, r);
      }

      return ret;
    }
  };
}  // namespace haar_lib
#line 2 "Mylib/Typical/range_set_query.cpp"
#include <algorithm>
#include <tuple>
#include <vector>
#line 2 "Mylib/DataStructure/FenwickTree/fenwick_tree_add.cpp"
#include <cassert>
#line 4 "Mylib/DataStructure/FenwickTree/fenwick_tree_add.cpp"

namespace haar_lib {
  template <typename T>
  class fenwick_tree_add {
  public:
    using value_type = T;

  private:
    int size_;
    std::vector<value_type> data_;

  public:
    fenwick_tree_add() {}
    fenwick_tree_add(int size) : size_(size), data_(size + 1, 0) {}

    void update(int i, value_type val) {
      assert(0 <= i and i < size_);
      i += 1;  // 1-index

      while (i <= size_) {
        data_[i] = data_[i] + val;
        i += i & (-i);
      }
    }

    value_type fold(int i) const {  // [0, i)
      assert(0 <= i and i <= size_);
      value_type ret = 0;

      while (i > 0) {
        ret = ret + data_[i];
        i -= i & (-i);
      }

      return ret;
    }

    value_type fold(int l, int r) const {  // [l, r)
      assert(0 <= l and l <= r and r <= size_);
      return fold(r) - fold(l);
    }

    value_type operator[](int x) const {
      return fold(x, x + 1);
    }
  };
}  // namespace haar_lib
#line 6 "Mylib/Typical/range_set_query.cpp"

namespace haar_lib {
  template <typename T>
  class range_set_query {
    std::vector<int> a_;
    std::vector<std::tuple<int, int, int>> qs_;
    int N_;

  public:
    range_set_query() {}
    range_set_query(std::vector<T> a) : N_(a.size()) {
      auto temp = a;
      std::sort(temp.begin(), temp.end());
      temp.erase(std::unique(temp.begin(), temp.end()), temp.end());

      for (auto x : a) {
        const int i = std::lower_bound(temp.begin(), temp.end(), x) - temp.begin();
        a_.push_back(i);
      }
    }

    void add(int l, int r) {  // [l, r)
      const int i = qs_.size();
      qs_.emplace_back(r, l, i);
    }

    auto solve() {
      std::sort(qs_.begin(), qs_.end());

      fenwick_tree_add<int> b(N_);

      const int Q = qs_.size();
      std::vector<int> last_index(N_, -1), ret(Q);

      int cur = 0;
      for (auto [r, l, i] : qs_) {
        while (cur < r) {
          if (last_index[a_[cur]] != -1) {
            b.update(last_index[a_[cur]], -1);
          }

          last_index[a_[cur]] = cur;
          b.update(last_index[a_[cur]], 1);

          ++cur;
        }

        ret[i] = b.fold(l, r);
      }

      return ret;
    }
  };
}  // namespace haar_lib
Back to top page