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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>

typedef long long ll;

constexpr ll prime_mod = 468395662504823LL;
constexpr ll prime_mod2 = 553559562581LL;
constexpr ll prime_multiplier = 1303LL;
constexpr ll prime_multiplier2 = 21023LL;
constexpr ll prime_start = 37171397LL;
constexpr ll prime_start2 = 20261LL;

class SwitchPoint {
 public:
  SwitchPoint(int coord, int index, int start)
      : coord_(coord), index_(index), start_(start) {}

  bool operator<(const SwitchPoint& rhs) {
    return coord_ < rhs.coord_;
  }

  int coord_;
  int index_;
  bool start_;
};

template<>
struct std::hash<std::pair<ll, ll>> {
  std::size_t operator()(const std::pair<ll, ll>& key) const {
    return std::hash<ll>()(key.first) + std::hash<ll>()(key.second);
  }
};

int CalculateBestSize(std::vector<SwitchPoint>* switch_points,
                      int dimension_limit,
                      ll* prime_factors, ll* prime_factors2) {
  ll hash = 0;
  ll hash2 = 0;
  int current_pos = 0;
  std::unordered_map<std::pair<ll, ll>, int> hash_to_size_map = {};
  std::sort(switch_points->begin(), switch_points->end());
  for (const SwitchPoint& sp : *switch_points) {
    int size = sp.coord_ - current_pos;
    hash_to_size_map[std::make_pair(hash, hash2)] += size;
    if (sp.start_) {
      hash += prime_factors[sp.index_];
      hash %= prime_mod;
      hash2 += prime_factors2[sp.index_];
      hash2 %= prime_mod2;
    } else {
      hash += prime_mod - prime_factors[sp.index_];
      hash %= prime_mod;
      hash2 += prime_mod2 - prime_factors2[sp.index_];
      hash2 %= prime_mod2;
    }
    current_pos = sp.coord_;
  }
  int size = dimension_limit - current_pos;
  hash_to_size_map[std::make_pair(hash, hash2)] += size;

  int max = 0;
  for (const auto&[hash, size] : hash_to_size_map) {
    max = std::max(size, max);
  }
  return max;
}

int main() {
  int n, x, y;
  scanf("%d %d %d", &n, &x, &y);

  ll* prime_factors = new ll[n];
  ll* prime_factors2 = new ll[n];

  ll current_factor = prime_start;
  ll current_factor2 = prime_start2;

  for (int i = 0; i < n; i++) {
    prime_factors[i] = current_factor;
    prime_factors2[i] = current_factor2;
    current_factor *= prime_multiplier;
    current_factor %= prime_mod;
    current_factor2 *= prime_multiplier2;
    current_factor2 %= prime_mod2;
  }

  std::vector<SwitchPoint> horizontal;
  std::vector<SwitchPoint> vertical;
  for (int i = 0; i < n; i++) {
    int x1, x2, y1, y2;
    scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
    if (x1 > x2) std::swap(x1, x2);
    if (y1 > y2) std::swap(y1, y2);
    horizontal.emplace_back(x1, i, true);
    horizontal.emplace_back(x2, i, false);
    vertical.emplace_back(y1, i, true);
    vertical.emplace_back(y2, i, false);
  }

  int best_width =
      CalculateBestSize(&horizontal, x, prime_factors, prime_factors2);
  int best_height =
      CalculateBestSize(&vertical, y, prime_factors, prime_factors2);

  std::cout << ((ll) best_height) * ((ll) best_width) << std::endl;
  return 0;
}