座標圧縮
概要
数列
ここで座標圧縮とは以下のように, 数列の各要素を全体において 0-indexed で何番目に小さいかを表す数値に置換することをいう.
- 圧縮前:
- 圧縮後:
計算量
与えられた数列の長さを
Snippet
C++
cpp
template <class T> std::vector<int> shrink_coordinate(std::vector<T> &a) {
std::vector<T> b = a;
std::sort(b.begin(), b.end());
b.erase(std::unique(b.begin(), b.end()), b.end());
int N = a.size();
std::vector<int> res(N);
for (int i = 0; i < N; i++) {
res[i] = std::lower_bound(b.begin(), b.end(), a[i]) - b.begin();
}
return res;
}
Python
python
def shrink_coordinate(a):
b = sorted(list(set(a)))
table = {v: k for k, v in enumerate(b)}
return list(map(lambda x: table[x], a))
解説
座標圧縮をするにはまず元の数列
数列 std::map
などを使って, 元の数列の要素と座標圧縮後の数列の要素の組としたデータを持つことができる.
C++ の std::map
は定数倍が遅いので, 数列
そのため, C++ では二分探索を行い, Python では辞書を使ってテーブルを持つように実装している.
検証
- ABC036-C: 座圧
- ABC113-C: ID
- ABC213-C: Reorder Cards
- ABC188-D: Sunuke Prime
- JOI 2012-2013 予選 問題5: 魚の生息範囲 (Fish)