結果
| 問題 |
No.8016 unordered_mapなるたけ落とすマン
|
| ユーザー |
|
| 提出日時 | 2020-05-22 12:32:38 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 44 ms / 1,000 ms |
| コード長 | 4,785 bytes |
| コンパイル時間 | 1,931 ms |
| コンパイル使用メモリ | 172,380 KB |
| 実行使用メモリ | 9,944 KB |
| 最終ジャッジ日時 | 2024-10-04 09:28:54 |
| 合計ジャッジ時間 | 5,712 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 48 |
ソースコード
#include <vector>
#include <cstdint>
#include <set>
template<class Key, class Value, class Hash>
struct hash_map {
using size_type = std::size_t;
using key_type = Key;
using value_type = Value;
using pair_type = std::pair<key_type, value_type>;
enum class State: std::uint8_t {
INACTIVE,
ACTIVE,
FILLED
};
Hash hashf;
std::vector<State> st;
std::vector<pair_type> bck;
size_type mask;
size_type prode;
size_type sz;
hash_map():
mask(0), prode(-1), sz(0) {
}
size_type find_empty(const key_type& key) {
size_type h = hashf(key);
for(size_type delta = 0;;delta++) {
size_type i = (h + delta) & mask;
if(st[i] != State::FILLED) {
if(prode < delta) prode = delta;
return i;
}
}
}
size_type find_filled(const key_type& key) {
if(sz == 0) return size_type(-1);
size_type h = hashf(key);
for(size_type delta = 0; delta <= prode; delta++) {
size_type i = (h + delta) & mask;
if(st[i] == State::FILLED) {
if(bck[i].first == key) {
return i;
}
}
else if(st[i] == State::INACTIVE) {
return size_type(-1);
}
}
return size_type(-1);
}
size_type find_or_allocate(const key_type& key) {
size_type h = hashf(key);
bool hole = false;
size_type delta = 0;
for(; delta <= prode; delta++) {
size_type i = (h + delta) & mask;
if(st[i] == State::FILLED) {
if(bck[i].first == key) return i;
}
else if(st[i] == State::INACTIVE) return i;
else {
hole = true;
}
}
if(!hole) return size_type(-1);
for(; ; delta++) {
size_type i = (h + delta) & mask;
if(st[i] != State::FILLED) {
prode = delta;
return i;
}
}
}
void reserve(int next_cnt) {
size_type required_cnt = next_cnt + (next_cnt >> 1) + 1;
if(required_cnt <= bck.size()) {
return;
}
next_cnt = 4;
while(next_cnt < required_cnt) next_cnt <<= 1;
std::vector<State> old_st(next_cnt, State::INACTIVE);
std::vector<pair_type> old_bck(next_cnt);
std::swap(old_st, st);
std::swap(old_bck, bck);
mask = next_cnt - 1;
sz = 0;
prode = -1;
for(size_type pos = 0; pos < old_bck.size(); pos++) {
if(old_st[pos] == State::FILLED) {
size_type i = find_empty(old_bck[pos].first);
st[i] = State::FILLED;
bck[i] = std::move(old_bck[pos]);
sz += 1;
}
}
}
void insert(const key_type& key, const value_type& val) {
reserve(sz + 1);
size_type i = find_or_allocate(key);
if(st[i] != State::FILLED) {
st[i] = State::FILLED;
bck[i] = pair_type(key, val);
sz++;
}
else {
bck[i] = pair_type(key, val);
}
}
bool erase(const key_type& key) {
size_type i = find_filled(key);
if(i == size_type(-1)) {
return false;
}
else {
st[i] = State::ACTIVE;
bck[i].~pair_type();
sz--;
return true;
}
}
pair_type* get(const key_type& key) {
size_type i = find_filled(key);
if(i == size_type(-1)) {
return nullptr;
}
else {
return &bck[i];
}
}
template<class Func>
void search_all(Func func) {
for(size_type i = 0; i < bck.size(); i++) {
if(st[i] == State::FILLED) {
size_type res = func(bck[i]);
if(res & 0b10) {
st[i] = State::ACTIVE;
bck[i].~pair_type();
sz--;
}
if(res & 0b01) {
return;
}
}
}
}
};
struct Hashu32 {
std::uint32_t operator()(std::uint32_t key) {
int c2=0x27d4eb2d; // a prime or an odd constant
key = (key ^ 61) ^ (key >> 16);
key = key + (key << 3);
key = key ^ (key >> 4);
key = key * c2;
key = key ^ (key >> 15);
return key;
}
};
struct Hashu64 {
std::size_t operator()(std::uint64_t key) {
key = (~key) + (key << 18); // key = (key << 18) - key - 1;
key = key ^ (key >> 31);
key = key * 21; // key = (key + (key << 2)) + (key << 4);
key = key ^ (key >> 11);
key = key + (key << 6);
key = key ^ (key >> 22);
return (int) key;
}
};
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(int (i) = (s);(i) < (e);(i)++)
#define all(x) x.begin(),x.end()
int main(){
cin.tie(nullptr);
std::ios::sync_with_stdio(false);
int N, M;
cin >> N >> M;
hash_map<std::uint64_t, int, Hashu64> mp;
rep(i,0,N){
std::uint64_t a;
cin >> a;
auto p = mp.get(a);
i64 x = 0;
if(p) x = p->second;
mp.insert(a, x + 1);
}
rep(i,0,M) {
std::uint64_t a;
cin >> a;
auto p = mp.get(a);
i64 x = 0;
if(p) x = p->second;
cout << x << " \n"[i + 1 == M];
}
}