結果
| 問題 |
No.1726 [Cherry 3rd Tune B] ジャマイカビアポン
|
| コンテスト | |
| ユーザー |
KoD
|
| 提出日時 | 2021-10-29 22:03:32 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 425 ms / 3,000 ms |
| コード長 | 9,037 bytes |
| コンパイル時間 | 2,867 ms |
| コンパイル使用メモリ | 255,328 KB |
| 実行使用メモリ | 101,664 KB |
| 最終ジャッジ日時 | 2024-10-07 11:21:43 |
| 合計ジャッジ時間 | 9,383 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 39 |
ソースコード
#include <bits/stdc++.h>
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
class rep {
struct Iter {
usize itr;
constexpr Iter(const usize pos) noexcept : itr(pos) {}
constexpr void operator++() noexcept { ++itr; }
constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; }
constexpr usize operator*() const noexcept { return itr; }
};
const Iter first, last;
public:
explicit constexpr rep(const usize first, const usize last) noexcept : first(first), last(std::max(first, last)) {}
constexpr Iter begin() const noexcept { return first; }
constexpr Iter end() const noexcept { return last; }
};
__attribute__((target("avx2"))) constexpr u64 ceil_log2(const u64 x) {
u64 e = 0;
while (((u64)1 << e) < x) ++e;
return e;
}
u64 xorshift() {
static u64 state = std::chrono::system_clock::now().time_since_epoch().count();
state ^= state << 7;
state ^= state >> 9;
return state;
}
template <class K, class V, std::enable_if_t<std::is_integral_v<K>>* = nullptr> class IntegerHashTable {
using Self = IntegerHashTable;
enum class Ctrl : char { Empty, Full, Deleted };
union Slot {
std::pair<const K, V> pair;
std::pair<K, V> mut_pair;
Slot() {}
~Slot() {}
};
struct Data {
Ctrl ctrl;
Slot slot;
Data() : ctrl(Ctrl::Empty), slot() {}
~Data() {
if (ctrl == Ctrl::Full) slot.mut_pair.~pair();
}
};
struct Manager {
static inline constexpr u64 PHI = 11400714819323198485ull;
static inline const u64 RND = xorshift();
usize logn, size, full, deleted;
Manager() : logn(0), size(0), full(0), deleted(0) {}
void fix() {
logn = ceil_log2(3 * full);
size = (full == 0 ? 0 : (1 << logn));
deleted = 0;
}
bool balanced() const { return 2 * (full + deleted) <= size and 8 * full >= size; }
usize mask() const { return size - 1; }
usize index(const K& k) const {
u64 x = static_cast<u64>(k) ^ RND;
x ^= x >> (64 - logn);
return (x * PHI) >> (64 - logn);
}
};
Data* data;
Manager info;
usize find_key(const K& k, usize i) const {
while (data[i].ctrl != Ctrl::Empty) {
if (data[i].ctrl == Ctrl::Full and data[i].slot.pair.first == k) break;
i = (i + 1) & info.mask();
}
return i;
}
usize find_place(usize i) const {
while (data[i].ctrl == Ctrl::Full) i = (i + 1) & info.mask();
return i;
}
template <class... Args> void construct(const usize i, Args&&... args) {
new (&data[i].slot.mut_pair) std::pair<K, V>(std::forward<Args>(args)...);
}
void resize() {
Data* old_data = std::exchange(data, nullptr);
const usize old_len = info.size;
info.fix();
if (info.size) {
data = new Data[info.size];
for (const usize i : rep(0, old_len)) {
if (old_data[i].ctrl == Ctrl::Full) {
const usize k = find_place(info.index(old_data[i].slot.pair.first));
data[k].ctrl = Ctrl::Full;
construct(k, std::move(old_data[i].slot.mut_pair));
}
}
}
if (old_data) delete[] old_data;
}
public:
IntegerHashTable() noexcept : data(nullptr), info() {}
IntegerHashTable(const Self& other) noexcept : Self() { *this = other; }
IntegerHashTable(Self&& other) noexcept : Self() { *this = std::move(other); }
~IntegerHashTable() { clear(); }
class Iter {
friend class IntegerHashTable;
usize idx;
Self* self;
explicit Iter(const usize i, Self* s) : idx(i - 1), self(s) { next(); }
void next() {
while (++idx < self->info.size)
if (self->data[idx].ctrl == Ctrl::Full) return;
}
public:
bool operator!=(const Iter& other) const { return idx != other.idx or self != other.self; }
std::pair<const K, V>& operator*() const { return self->data[idx].slot.pair; }
void operator++() { next(); }
};
class ConstIter {
friend class IntegerHashTable;
usize idx;
const Self* self;
explicit ConstIter(const usize i, const Self* s) : idx(i - 1), self(s) { next(); }
void next() {
while (++idx < self->info.size)
if (self->data[idx].ctrl == Ctrl::Full) return;
}
public:
bool operator!=(const ConstIter& other) const { return idx != other.idx or self != other.self; }
const std::pair<const K, V>& operator*() const { return self->data[idx].slot.pair; }
void operator++() { next(); }
};
Self& operator=(const Self& other) noexcept {
if (this != &other) {
clear();
info = other.info;
info.fix();
if (info.size) {
data = new Data[info.size];
for (const usize i : rep(0, other.info.size)) {
if (other.data[i].ctrl == Ctrl::Full) {
const usize k = find_place(info.index(other.data[i].slot.pair.first));
data[k].ctrl = Ctrl::Full;
construct(k, other.data[i].slot.mut_pair);
}
}
}
}
return *this;
}
Self& operator=(Self&& other) noexcept {
if (this != &other) {
clear();
data = std::exchange(other.data, nullptr);
info = std::exchange(other.info, Manager());
}
return *this;
}
template <class... Args> std::pair<V*, bool> insert(const K& key, Args&&... args) {
usize idx = -1;
if (empty()) {
info.full += 1;
resize();
idx = info.index(key);
} else {
const usize pos = info.index(key);
usize i = find_key(key, pos);
if (data[i].ctrl == Ctrl::Full) return std::make_pair(&data[i].slot.pair.second, false);
i = find_place(pos);
info.full += 1;
info.deleted -= (data[i].ctrl == Ctrl::Deleted);
if (!info.balanced()) {
resize();
i = find_place(info.index(key));
}
idx = i;
}
data[idx].ctrl = Ctrl::Full;
construct(idx, std::piecewise_construct, std::forward_as_tuple(key),
std::forward_as_tuple(std::forward<Args>(args)...));
return std::make_pair(&data[idx].slot.pair.second, true);
}
bool erase(const K& key) {
if (empty()) return false;
const usize i = find_key(key, info.index(key));
if (data[i].ctrl == Ctrl::Full) {
info.full -= 1;
info.deleted += 1;
data[i].ctrl = Ctrl::Deleted;
data[i].slot.mut_pair.~pair();
if (!info.balanced()) resize();
return true;
}
return false;
}
V* find(const K& key) const {
if (empty()) return nullptr;
const usize i = find_key(key, info.index(key));
return data[i].ctrl == Ctrl::Full ? &data[i].slot.pair.second : nullptr;
}
void clear() {
if (data) {
delete[] data;
data = nullptr;
}
info = Manager();
}
usize size() const { return info.full; }
bool empty() const { return size() == 0; }
V& operator[](const K& key) { return *insert(key).first; }
Iter begin() { return Iter(0, this); }
Iter end() { return Iter(info.size, this); }
ConstIter begin() const { return ConstIter(0, this); }
ConstIter end() const { return ConstIter(info.size, this); }
};
template <class T> using Vec = std::vector<T>;
void main_() {
usize N, M;
std::cin >> N >> M;
Vec<i64> P(N);
for (auto& x : P) {
std::cin >> x;
}
Vec<i64> A(N), B(N), C(M), D(M);
for (const auto i : rep(0, N)) {
std::cin >> A[i] >> B[i];
}
for (const auto i : rep(0, M)) {
std::cin >> C[i] >> D[i];
}
i64 ans = 0;
for (const auto step : rep(0, 4)) {
if (step == 2) {
for (auto& x : B) {
x = -x;
}
}
IntegerHashTable<i64, i64> map;
for (const auto i : rep(0, N)) {
for (const auto j : rep(0, M)) {
map[(C[j] - A[i]) * 2000000005 + (D[j] - B[i])] += P[i];
}
}
for (const auto& [_, p] : map) {
ans = std::max(ans, p);
}
for (auto& x : A) {
x = -x;
}
}
std::cout << ans << '\n';
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
main_();
return 0;
}
KoD