#include <cassert>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <unordered_map>
#include <vector>
struct seg_event_t {
uint32_t position;
int idx;
};
// Around 60 bits
const uint64_t MODULUS_PRIME = 999999999999999989;
// const uint64_t MODULUS_PRIME = 99999999999999997;
std::vector<uint64_t> compute_hash_table(int max_n,
uint64_t advancement,
uint64_t modulus) {
std::vector<uint64_t> ret;
ret.reserve(max_n + 1);
uint64_t current = 1;
ret.push_back(1);
for (int i = 1; i <= max_n; i++) {
current = (current * advancement) % modulus;
ret.push_back(current);
assert(current != 1 && current != 0);
}
return ret;
}
uint64_t process_coord(std::vector<seg_event_t> evts,
const std::vector<uint64_t>& htable,
uint32_t limit) {
auto comparator = [](const seg_event_t& a, const seg_event_t& b) -> bool {
return a.position < b.position;
};
std::sort(evts.begin(), evts.end(), comparator);
std::unordered_map<uint64_t, uint64_t> area_for_set;
uint64_t set_marker = 0;
uint32_t previous_position = 0;
for (const auto e : evts) {
const auto length = e.position - previous_position;
area_for_set[set_marker] += length;
previous_position = e.position;
if (e.idx > 0) {
set_marker += htable[e.idx];
} else {
set_marker += MODULUS_PRIME - htable[-e.idx];
}
set_marker %= MODULUS_PRIME;
}
area_for_set[set_marker] += limit - previous_position;
uint64_t max = 0;
for (auto p : area_for_set) {
max = std::max(max, p.second);
}
return max;
}
int main() {
unsigned int n, X, Y;
(void)scanf("%u %u %u", &n, &X, &Y);
std::vector<seg_event_t> hor_evts, ver_evts;
hor_evts.reserve(2 * n);
ver_evts.reserve(2 * n);
for (int i = 1; i <= (int)n; i++) {
unsigned int x1, y1, x2, y2;
(void)scanf("%u %u %u %u", &x1, &y1, &x2, &y2);
hor_evts.push_back(seg_event_t{x1, i});
hor_evts.push_back(seg_event_t{x2, -i});
ver_evts.push_back(seg_event_t{y1, i});
ver_evts.push_back(seg_event_t{y2, -i});
}
const auto htable = compute_hash_table(n, 7, MODULUS_PRIME);
const auto solution = process_coord(std::move(hor_evts), htable, X) *
process_coord(std::move(ver_evts), htable, Y);
printf("%llu\n", (unsigned long long int)solution);
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | #include <cassert> #include <cstdint> #include <cstdio> #include <cstdlib> #include <algorithm> #include <unordered_map> #include <vector> struct seg_event_t { uint32_t position; int idx; }; // Around 60 bits const uint64_t MODULUS_PRIME = 999999999999999989; // const uint64_t MODULUS_PRIME = 99999999999999997; std::vector<uint64_t> compute_hash_table(int max_n, uint64_t advancement, uint64_t modulus) { std::vector<uint64_t> ret; ret.reserve(max_n + 1); uint64_t current = 1; ret.push_back(1); for (int i = 1; i <= max_n; i++) { current = (current * advancement) % modulus; ret.push_back(current); assert(current != 1 && current != 0); } return ret; } uint64_t process_coord(std::vector<seg_event_t> evts, const std::vector<uint64_t>& htable, uint32_t limit) { auto comparator = [](const seg_event_t& a, const seg_event_t& b) -> bool { return a.position < b.position; }; std::sort(evts.begin(), evts.end(), comparator); std::unordered_map<uint64_t, uint64_t> area_for_set; uint64_t set_marker = 0; uint32_t previous_position = 0; for (const auto e : evts) { const auto length = e.position - previous_position; area_for_set[set_marker] += length; previous_position = e.position; if (e.idx > 0) { set_marker += htable[e.idx]; } else { set_marker += MODULUS_PRIME - htable[-e.idx]; } set_marker %= MODULUS_PRIME; } area_for_set[set_marker] += limit - previous_position; uint64_t max = 0; for (auto p : area_for_set) { max = std::max(max, p.second); } return max; } int main() { unsigned int n, X, Y; (void)scanf("%u %u %u", &n, &X, &Y); std::vector<seg_event_t> hor_evts, ver_evts; hor_evts.reserve(2 * n); ver_evts.reserve(2 * n); for (int i = 1; i <= (int)n; i++) { unsigned int x1, y1, x2, y2; (void)scanf("%u %u %u %u", &x1, &y1, &x2, &y2); hor_evts.push_back(seg_event_t{x1, i}); hor_evts.push_back(seg_event_t{x2, -i}); ver_evts.push_back(seg_event_t{y1, i}); ver_evts.push_back(seg_event_t{y2, -i}); } const auto htable = compute_hash_table(n, 7, MODULUS_PRIME); const auto solution = process_coord(std::move(hor_evts), htable, X) * process_coord(std::move(ver_evts), htable, Y); printf("%llu\n", (unsigned long long int)solution); return 0; } |
English