【数据结构】静态map
map可以动态进行插入删除等操作,但其常数太高了。
如果只用一个有序数组来存储的话,那么可以提供更好的查询复杂度的常数,同时在构建的时候由于不需要保存额外的信息所以非常节约内存:需要小心的是这个map只能找到第一个重复的元素,如果需要进行覆盖操作的话,一般还是得使用BST去做。当然也可以get之后对其进行赋值,但是要小心这样会破坏掉数组的有序性,必须要sort之后才能重新使用。如果遇到这种需要替换的情况的话,还是得弄一个辅助vector比较简单。也就是下文中使用两倍空间的做法(毕竟要优先保证时间复杂度)
这个数据结构比map要快很多,同时非常节约空间,代价是在sort之后不能进行任何修改操作,只适用于查询比修改多非常多的情况。它甚至不能去重,建立时在数据外侧自己想办法去重或者用下文的双倍空间的版本吧。
这个本身就是定制的高速数据结构,要非常小心使用
简单版本的,直接sort,省去了inplace_merge的额外空间。
template <class key_type, class value_type>
struct const_map {
private:
const value_type empty_value = default_value<value_type>::empty_value;
const value_type min_value = default_value<value_type>::min_value;
vector<pair<key_type, value_type>> vec;
int vec_sorted_len;
decltype (vec.begin()) find (const key_type& key) {
auto it = lower_bound (key);
if (it == vec.end() || it->first != key) {
return vec.end();
}
return it;
}
public:
void clear() {
vec.clear();
}
void reserve (int n) {
vec.reserve (n);
}
void sort() {
std::sort (vec.begin(), vec.end());
}
int count (const key_type& key) {
auto it = find (key);
if (it == vec.end()) {
return 0;
}
return 1;
}
const value_type& get_value (const key_type& key) {
auto it = find (key);
if (it == vec.end()) {
return empty_value;
}
return it->second;
}
void set_value (const key_type& key, const value_type& value) {
vec.push_back (make_pair (key, value));
}
decltype (vec.begin()) lower_bound (const key_type& key) {
return std::lower_bound (vec.begin(), vec.end(), make_pair (key, min_value));
}
decltype (vec.begin()) begin () {
return vec.begin();
}
decltype (vec.begin()) end () {
return vec.end();
}
};
下面这个好像是画蛇添足的版本,略微优化了一点点sort操作的复杂度,但引入了很多不必要的东西。
template<typename>
struct default_value;
template<>
struct default_value<int> {
static constexpr int empty_value = 0;
static constexpr int min_value = -INF;
static constexpr int max_value = INF;
};
template<>
struct default_value<ll> {
static constexpr ll empty_value = 0LL;
static constexpr ll min_value = -LINF;
static constexpr ll max_value = LINF;
};
template <class key_type, class value_type>
struct const_map {
private:
const value_type empty_value = default_value<value_type>::empty_value;
const value_type min_value = default_value<value_type>::min_value;
vector<pair<key_type, value_type>> vec;
int vec_sorted_len;
decltype (vec.begin()) find (const key_type& key) {
auto it = lower_bound (vec.begin(), vec.begin() + vec_sorted_len, make_pair (key, min_value));
if (it == vec.begin() + vec_sorted_len || it->first != key) {
it = vec.end();
}
return it;
}
public:
void clear() {
vec.clear();
vec_sorted_len = 0;
}
void sort() {
std::sort (vec.begin() + vec_sorted_len, vec.end());
std::inplace_merge (vec.begin(), vec.begin() + vec_sorted_len, vec.end());
vec_sorted_len = vec.size();
}
int count (const key_type& key) {
auto it = find (key);
if (it != vec.end()) {
return 1;
}
return 0;
}
const value_type& get_value (const key_type& key) {
auto it = find (key);
if (it != vec.end()) {
return it->second;
}
return empty_value;
}
void set_value (const key_type& key, const value_type& value) {
vec.push_back (make_pair (key, value));
}
const value_type& Get (const key_type& key) {
return get_value (key);
}
void Set (const key_type& key, const value_type& value) {
set_value (key, value);
}
};
初代是下面这个,容易看出来是怎么运行的。
struct my_map {
vector<pair<pii, int>> vec;
void clear() {
vec.clear();
}
int count (const pii & key) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, -INF));
return it == vec.end() ? 0 : it->first == key ? 1 : 0;
}
void init() {
sort (vec.begin(), vec.end());
vec.resize (unique (vec.begin(), vec.end()) - vec.begin());
}
void insert (const pii & key, int value) {
vec.push_back ({key, value});
}
int get (const pii & key) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, -INF));
return it ->second;
}
};
这里还需要研究一下方括号运算符、for-each使用的迭代器。等的写法,使其可以完全替代map。
TODO:无序的版本。
一个可以使用方括号的方案,但是实际上非常多限制,时间和空间都有一点浪费,还容易出bug,记得使用带有序意义的方法之前都要init:
template<typename>
struct default_value;
template<>
struct default_value<int> {
static constexpr int empty_value = 0;
static constexpr int min_value = -INF;
static constexpr int max_value = INF;
};
template <class _Key, class _Tp>
struct my_map {
typedef _Key key_type;
typedef _Tp data_type;
data_type data_type_empty_value = default_value<data_type>::empty_value;
data_type data_type_min_value = default_value<data_type>::min_value;
typedef pair<key_type, data_type> node_type;
vector<node_type> vec, temp_vec;
void clear() {
vec.clear();
temp_vec.clear();
}
int count (const pii & key) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, data_type_min_value));
return it == vec.end() ? 0 : it->first == key ? 1 : 0;
}
void init() {
sort (vec.begin(), vec.end());
sort (temp_vec.begin(), temp_vec.end());
auto vec_it = vec.begin();
auto temp_vec_it = temp_vec.begin();
vector<node_type> result_vec;
while (vec_it != vec.end() || temp_vec_it != temp_vec.end()) {
if (vec_it == vec.end()) {
result_vec.push_back (*temp_vec_it);
++temp_vec_it;
continue;
}
if (temp_vec_it == temp_vec.end()) {
result_vec.push_back (*vec_it);
++vec_it;
continue;
}
if (vec_it->first > temp_vec_it ->first) {
result_vec.push_back (*temp_vec_it);
++temp_vec_it;
continue;
}
if (vec_it->first < temp_vec_it ->first) {
result_vec.push_back (*vec_it);
++vec_it;
continue;
}
result_vec.push_back (*temp_vec_it);
++vec_it;
++temp_vec_it;
continue;
}
vec = result_vec;
temp_vec.clear();
}
const data_type& get_value (const key_type& key) {
if (count (key) > 0) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, data_type_min_value));
return it->second;
}
return data_type_empty_value;
}
// 为了节省维持map的复杂度所带来的常数,使用上的特殊约定是必须的
void set_value (const key_type& key, const data_type& data) {
// 新的值要在init之后才会生效
// 如果原本已有这个key,那么可以覆盖
// 如果在init之前,多次插入同一个key,会出现奇怪的事情
temp_vec.push_back (make_pair (key, data));
}
// 为了节省维持map的复杂度所带来的常数,使用上的特殊约定是必须的
data_type& operator[] (const key_type& key) {
if (count (key) > 0) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, data_type_min_value));
// 这里的方括号运算符很诡异,返回的是原本的一个拷贝,新的值要在init之后才会生效
// 如果原本已有这个key,那么可以覆盖
// 如果在init之前,多次插入同一个key,会出现奇怪的事情
temp_vec.push_back (make_pair (key, it->second));
return temp_vec.back().second;
}
temp_vec.push_back (make_pair (key, data_type_empty_value));
return temp_vec.back().second;
}
};
下面的方法通过拷贝vec去掉归并来提高速度,代价是牺牲空间:
template<typename>
struct default_value;
template<>
struct default_value<int> {
static constexpr int empty_value = 0;
static constexpr int min_value = -INF;
static constexpr int max_value = INF;
};
template <class _Key, class _Tp>
struct my_map {
typedef _Key key_type;
typedef _Tp data_type;
data_type data_type_empty_value = default_value<data_type>::empty_value;
data_type data_type_min_value = default_value<data_type>::min_value;
typedef pair<key_type, data_type> node_type;
vector<node_type> vec, temp_vec;
void clear() {
vec.clear();
temp_vec.clear();
}
int count (const pii & key) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, data_type_min_value));
return it == vec.end() ? 0 : it->first == key ? 1 : 0;
}
void init() {
sort (temp_vec.begin(), temp_vec.end());
vec = temp_vec;
}
const data_type& get_value (const key_type& key) {
if (count (key) > 0) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, data_type_min_value));
return it->second;
}
return data_type_empty_value;
}
// 为了节省维持map的复杂度所带来的常数,使用上的特殊约定是必须的
void set_value (const key_type& key, const data_type& data) {
// 新的值要在init之后才会生效
// 如果原本已有这个key,那么可以覆盖
// 如果在init之前,多次插入同一个key,会出现奇怪的事情
temp_vec.push_back (make_pair (key, data));
}
// 为了节省维持map的复杂度所带来的常数,使用上的特殊约定是必须的
data_type& operator[] (const key_type& key) {
if (count (key) > 0) {
auto it = lower_bound (vec.begin(), vec.end(), make_pair (key, data_type_min_value));
// 这里的方括号运算符很诡异,返回的是原本的一个拷贝,新的值要在init之后才会生效
// 如果原本已有这个key,那么可以覆盖
// 如果在init之前,多次插入同一个key,会出现奇怪的事情
temp_vec.push_back (make_pair (key, it->second));
return temp_vec.back().second;
}
temp_vec.push_back (make_pair (key, data_type_empty_value));
return temp_vec.back().second;
}
};
然而既然是CP,最推荐的方法是下面的:
template<typename>
struct default_value;
template<>
struct default_value<int> {
static constexpr int empty_value = 0;
static constexpr int min_value = -INF;
static constexpr int max_value = INF;
};
template< class T >
using remove_reference_t = typename remove_reference<T>::type;
template <class _Key, class _Tp>
struct my_map {
typedef _Key key_type;
typedef _Tp data_type;
data_type data_type_empty_value = default_value<data_type>::empty_value;
data_type data_type_min_value = default_value<data_type>::min_value;
typedef pair<key_type, data_type> node_type;
vector<node_type> vec;
int vec_sorted_len;
void clear() {
vec.clear();
vec_sorted_len = 0;
}
int count (const pii & key) {
auto it = lower_bound (vec.begin(), vec.begin() + vec_sorted_len, make_pair (key, data_type_min_value));
return it != vec.end() && it->first == key;
}
void sort() {
std::sort (vec.begin() + vec_sorted_len, vec.end());
inplace_merge (vec.begin(), vec.begin() + vec_sorted_len, vec.end());
vec_sorted_len = vec.size();
}
const data_type& get_value (const key_type& key) {
if (count (key) > 0) {
auto it = lower_bound (vec.begin(), vec.begin() + vec_sorted_len, make_pair (key, data_type_min_value));
return it->second;
}
return data_type_empty_value;
}
void set_value (const key_type& key, const data_type& data) {
vec.push_back (make_pair (key, data));
}
const data_type& G (const key_type& key) {
return get_value (key);
}
void S (const key_type& key, const data_type& data) {
set_value (key, data);
}
};