Language: C++

#ifndef Local
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma comment(linker, "/STACK:1024000000,1024000000")
#endif

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define popCnt(x) (__builtin_popcountll(x))
typedef long long Long;

typedef long double Double;
const Double EPS = 1e-10;

bool areEqual(Double x, Double y, Double eps = EPS) {
  auto diff = abs(x - y);
  if (diff < eps) return true;
  if (min(x, y) < eps) return false;
  return diff / max(x, y) < eps;
}

bool isZero(Double x, Double eps = EPS) {
  return abs(x) <= eps;
}

struct Point {
  Double x = 0, y = 0;
  Point(Double x, Double y) :
    x(x), y(y) {
  }
  Point() {
  }
  Point operator +(const Point &p) const {
    return Point { x + p.x, y + p.y };
  }

  Point operator -(const Point &p) const {
    return Point { x - p.x, y - p.y };
  }
  Point operator *(Double c) const {
    return Point(x * c, y * c);
  }
  Point operator /(Double c) {
    return Point(x / c, y / c);
  }
  bool operator<(const Point &p) const {
    return areEqual(x, p.x) ? (y < p.y) : (x < p.x);
  }
  bool operator>(const Point& p) const {
    return areEqual(x, p.x) ? (y > p.y) : (x > p.x);
  }
  bool operator==(const Point &p) const {
    return areEqual(x, p.x) && areEqual(y, p.y);
  }
  bool operator!=(const Point& p) const {
    return !(*this == p);
  }
};

Double dot(Point p, Point q) {
  return p.x * q.x + p.y * q.y;
}

Double dist2(Point p, Point q) {
  return dot(p - q, p - q);
}

Double cross(Point p, Point q) {
  return p.x * q.y - p.y * q.x;
}

Point norm(Point x, Double l) {
  return x * sqrt(l * l / dot(x, x));
}

istream &operator>>(istream &is, Point &p) {
  return is >> p.x >> p.y;
}

Point RotateCCW90(Point p) {
  return Point(-p.y, p.x);
}

Point RotateCCW(Point p, Double t) {
  return Point(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
}

// project point c onto line through a and b (assuming a != b)
Point ProjectPointLine(Point a, Point b, Point c) {
  return a + (b - a) * dot(c - a, b - a) / dot(b - a, b - a);
}

// project point c onto line segment through a and b (assuming a != b)
Point ProjectPointSegment(Point a, Point b, Point c) {
  Double r = dot(c - a, b - a), d = dot(b - a, b - a);
  if (r < 0) return a;
  if (r > d) return b;
  return a + (b - a) * r / d;
}

Point reflectAroundLine(Point p, Point a, Point b) {
  return ProjectPointLine(p, a, b) * 2 - p;
}

bool LinesParallel(const Point& a, const Point& b, const Point& c,
  const Point& d) {
  return isZero(cross(b - a, c - d));
}

bool LinesCollinear(const Point& a, const Point& b, const Point& c,
  const Point& d) {
  return LinesParallel(a, b, c, d) && isZero(cross(b - c, a - c));
}

// Returns 1 if CW, 0 if collinear, -1 if ACW.
int getDirection(const Point& a, const Point& b, const Point& c) {
  auto value = cross(c - a, b - a);
  if (isZero(value)) return 0;
  return 2 * (value > 0) - 1;
}

// Checks if c lies in the range [a,b].
bool checkInRange(Double a, Double b, Double c, Double eps = EPS) {
  if (areEqual(a, c)) return true;
  if (areEqual(b, c)) return true;
  return a <= c && c <= b;
}

// Assuming that c already lies on the straight line ab,
// returns true if c lies on the segment ab.
bool onSegment(const Point& a, const Point& b, const Point& c) {
  return checkInRange(a.x, b.x, c.x) && checkInRange(a.y, b.y, c.y);
}

// Determine if a to b intersects with c to d.
bool SegmentsIntersect(const Point& a, const Point& b, const Point& c,
  const Point& d) {
  // Handles collinear cases.
  auto d1 = getDirection(c, d, a);
  auto d2 = getDirection(c, d, b);
  auto d3 = getDirection(a, b, c);
  auto d4 = getDirection(a, b, d);

  // tmp
  if (LinesCollinear(a, b, c, d)
    && (onSegment(a, b, c) && onSegment(a, b, d)
      || onSegment(c, d, a) && onSegment(c, d, b))) {
    return false;
  }

  if (d1 == 0 && onSegment(c, d, a)) return true;
  if (d2 == 0 && onSegment(c, d, b)) return true;
  if (d3 == 0 && onSegment(a, b, c)) return true;
  if (d4 == 0 && onSegment(a, b, d)) return true;
  if (d1 == 0 || d2 == 0 || d3 == 0 || d4 == 0) return false;
  return (((d1 > 0) == (d2 < 0)) && ((d3 > 0) == (d4 < 0)));
}

// ST Line ab intersect ST Line cd assuming unique intersection exists
// for line segments, check if segments intersect first
Point ComputeLineIntersection(Point a, Point b, Point c, Point d) {
  b = b - a;
  d = c - d;
  c = c - a;
  return a + b * cross(c, d) / cross(b, d); // cross(b,d) != 0
}

typedef array<Point, 2> Segment;

struct Event {
  int x, type, y, id;

  tuple<int, int, int, int> getTuple() const {
    return make_tuple(x, type, y, id);
  }

  bool operator <(const Event& other) const {
    return getTuple() < other.getTuple();
  }

  Event(int x, int type, int y_end, int id) :
    x(x), type(type), y(y_end), id(id) {
  }
};

struct SetComparator {
  static vector<Segment> segments;
  bool operator()(int a, int b) const {
    if (segments[a][0].x == segments[b][0].x) {
      return segments[a][0].y < segments[b][0].y;
    }
    if (segments[a][0].y == segments[a][1].y
      && segments[b][0].y == segments[b][1].y
      && segments[a][0].y == segments[b][0].y) {
      return segments[a][0].x < segments[b][0].x;
    }
    if (segments[a][0] > segments[b][0]) {
      int dir = getDirection(segments[b][0], segments[b][1], segments[a][0]);
      return dir > 0;
    }
    int dir = getDirection(segments[a][0], segments[a][1], segments[b][0]);
    return dir < 0;
  }
};

vector<Segment> SetComparator::segments;

bool noIntersection(const vector<Segment>& segments) {
  int n = segments.size();
  vector<Event> events;
  for (int i = 0; i < n; ++i) {
    events.emplace_back(segments[i][0].x, segments[i][0] > segments[i][1],
      segments[i][0].y, i);
    events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      segments[i][1].y, i);
  }

  sort(events.begin(), events.end());

  SetComparator::segments = segments;
  set<int, SetComparator> st;

  for (auto& event : events) {
    if (event.type == 0) {
      auto nxt = st.upper_bound(event.id);
      if (nxt != st.end()) {
        if (SegmentsIntersect(segments[event.id][0], segments[event.id][1],
          segments[*nxt][0], segments[*nxt][1])) return false;
      }

      if (nxt != st.begin()) {
        --nxt;
        if (SegmentsIntersect(segments[event.id][0], segments[event.id][1],
          segments[*nxt][0], segments[*nxt][1])) return false;
      }

      st.insert(event.id);

    } else {
      st.erase(event.id);
      auto nxt = st.upper_bound(event.id);
      if (nxt != st.end() && nxt != st.begin()) {
        auto before = nxt;
        --before;
        if (SegmentsIntersect(segments[*before][0], segments[*before][1],
          segments[*nxt][0], segments[*nxt][1])) {
          return false;
        }
      }
    }
  }

  return true;
}

bool onBorder(const Point& p, int r, int c) {
  return isZero(p.x) || isZero(p.y) || areEqual(p.x, r) || areEqual(p.y, c);
}

int main(int argc, char *argv[]) {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#ifdef Local
  freopen("test.in", "r", stdin);
#else
#define endl '\n'
#endif

  int r, c, n;
  cin >> r >> c >> n;

  vector<Segment> segments;

  while (n--) {
    Segment seg;
    cin >> seg[0] >> seg[1];
//    sort(seg.begin(), seg.end());
    if (onBorder(seg[0], r, c) && onBorder(seg[1], r, c)) {
      segments.emplace_back(seg);
    }
  }

  sort(segments.begin(), segments.end());
  cout << (noIntersection(segments) ? "YES" : "NO") << endl;

}


Compiler output:
a.cc: In function 'bool noIntersection(const std::vector<std::array<Point, 2> >&)':
a.cc:217:58: error: no match for 'operator<=' (operand types are 'const std::array<Point, 2>::value_type' {aka 'const Point'} and 'const std::array<Point, 2>::value_type' {aka 'const Point'})
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
In file included from /usr/include/c++/14/regex:68,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:181,
                 from a.cc:8:
/usr/include/c++/14/bits/regex.h:1154:5: note: candidate: 'template<class _BiIter> bool std::__cxx11::operator<=(const sub_match<_BiIter>&, const sub_match<_BiIter>&)'
 1154 |     operator<=(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1154:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/regex.h:1260:5: note: candidate: 'template<class _Bi_iter, class _Ch_traits, class _Ch_alloc> bool std::__cxx11::operator<=(__sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>&, const sub_match<_BiIter>&)'
 1260 |     operator<=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1260:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'std::__cxx11::__sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/regex.h:1353:5: note: candidate: 'template<class _Bi_iter, class _Ch_traits, class _Ch_alloc> bool std::__cxx11::operator<=(const sub_match<_BiIter>&, __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>&)'
 1353 |     operator<=(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1353:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/regex.h:1427:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator<=(const typename std::iterator_traits<_Iter>::value_type*, const sub_match<_BiIter>&)'
 1427 |     operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1427:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/regex.h:1521:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator<=(const sub_match<_BiIter>&, const typename std::iterator_traits<_Iter>::value_type*)'
 1521 |     operator<=(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1521:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/regex.h:1599:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator<=(const typename std::iterator_traits<_Iter>::value_type&, const sub_match<_BiIter>&)'
 1599 |     operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1599:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/regex.h:1699:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator<=(const sub_match<_BiIter>&, const typename std::iterator_traits<_Iter>::value_type&)'
 1699 |     operator<=(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1699:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
In file included from /usr/include/c++/14/bits/stl_algobase.h:64,
                 from /usr/include/c++/14/algorithm:60,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:51:
/usr/include/c++/14/bits/stl_pair.h:1064:5: note: candidate: 'template<class _T1, class _T2> constexpr bool std::operator<=(const pair<_T1, _T2>&, const pair<_T1, _T2>&)'
 1064 |     operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:1064:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::pair<_T1, _T2>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
In file included from /usr/include/c++/14/bits/stl_algobase.h:67:
/usr/include/c++/14/bits/stl_iterator.h:469:5: note: candidate: 'template<class _Iterator> constexpr bool std::operator<=(const reverse_iterator<_Iterator>&, const reverse_iterator<_Iterator>&)'
  469 |     operator<=(const reverse_iterator<_Iterator>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:469:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::reverse_iterator<_Iterator>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/stl_iterator.h:513:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr bool std::operator<=(const reverse_iterator<_Iterator>&, const reverse_iterator<_IteratorR>&)'
  513 |     operator<=(const reverse_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:513:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::reverse_iterator<_Iterator>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/stl_iterator.h:1704:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr bool std::operator<=(const move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)'
 1704 |     operator<=(const move_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1704:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::move_iterator<_IteratorL>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/bits/stl_iterator.h:1767:5: note: candidate: 'template<class _Iterator> constexpr bool std::operator<=(const move_iterator<_IteratorL>&, const move_iterator<_IteratorL>&)'
 1767 |     operator<=(const move_iterator<_Iterator>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1767:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'const std::array<Point, 2>::value_type' {aka 'const Point'} is not derived from 'const std::move_iterator<_IteratorL>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
In file included from /usr/include/c++/14/bits/basic_string.h:47,
                 from /usr/include/c++/14/string:54,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52:
/usr/include/c++/14/string_view:717:5: note: candidate: 'template<class _CharT, class _Traits> constexpr bool std::operator<=(basic_string_view<_CharT, _Traits>, basic_string_view<_CharT, _Traits>)'
  717 |     operator<=(basic_string_view<_CharT, _Traits> __x,
      |     ^~~~~~~~
/usr/include/c++/14/string_view:717:5: note:   template argument deduction/substitution failed:
a.cc:217:74: note:   'Point' is not derived from 'std::basic_string_view<_CharT, _Traits>'
  217 |     events.emplace_back(segments[i][1].x, segments[i][0] <= segments[i][1],
      |                                                                          ^
/usr/include/c++/14/string_view:724:5: note: candidate: 'template<class _CharT, class _Traits> constexpr bool std::operator<=(basic