Language: C++

#include <windows.h>
int WorkSize(void) {
    typedef struct {
        DWORD  cb;
        DWORD  PageFaultCount;
        SIZE_T PeakWorkingSetSize;
        SIZE_T WorkingSetSize;
        SIZE_T QuotaPeakPagedPoolUsage;
        SIZE_T QuotaPagedPoolUsage;
        SIZE_T QuotaPeakNonPagedPoolUsage;
        SIZE_T QuotaNonPagedPoolUsage;
        SIZE_T PagefileUsage;
        SIZE_T PeakPagefileUsage;
    } info_t;
    typedef BOOL(WINAPI*func_t)(HANDLE,info_t*,DWORD);
    static func_t func; static enum { FIRST,OK,ERR } flag;
    static HANDLE proc; info_t info; HINSTANCE dll;
    if (flag==FIRST) {
        if ((dll=LoadLibraryA("psapi"))==0) { flag=ERR; return 0; }
        func=(func_t)GetProcAddress(dll,"GetProcessMemoryInfo");
        if (func==0) { flag=ERR; return 0; }
        proc=GetCurrentProcess(); flag=OK;
    }
    if (flag==ERR) return 0;
    func(proc,&info,sizeof info); return(int)info.WorkingSetSize;
}

#include<vector>
#include<unordered_map>
#include<algorithm>
class Compression {
 public:
  Compression(const std::vector<int>& list) : value_(list) {
    std::sort(begin(value_), end(value_));
    value_.erase(std::unique(begin(value_), end(value_)), end(value_));
    for(int i = 0; i < value_.size(); ++i) index_[value_[i]] = i;
  }
  int size() const {return value_.size();}
  int index(const int v) const {return index_.at(v);}
  int operator[](const int i) const {return value_.at(i);}
 private:
  std::unordered_map<int, int> index_;
  std::vector<int> value_;
};

#include<unordered_map>
#include<utility>
template<typename T>
class UnionFind {
 public:
  void unite(const T& a, const T& b) {
    T x = find(a), y = find(b);
    if(rank_[x] < rank_[y]) std::swap(x, y);
    parent_[y] = x;
    if(rank_[x] == rank_[y]) rank_[x] += 1;
  }
  const T find(const T& x) {
    if(!parent_.count(x)) {
      rank_[x] = 1;
      return parent_[x] = x;
    }
    return (parent_[x] == x) ? x : (parent_[x] = find(parent_[x]));
  }
 private:
  std::unordered_map<T, T> parent_;
  std::unordered_map<T, int> rank_;
};

#include<bits/stdc++.h>
using namespace std;

// [left, right)
struct Node {
  int id, left, right;
  Node(int x) : id(2e9), left(x), right(2e9) {}
  Node(int i, int l, int r) : id(i), left(l), right(r) {}
  bool operator<(const Node& n) const {
    if(left != n.left) return left < n.left;
    if(right != n.right) return right < n.right;
    return id < n.id;
  }
};

class SegmentTree {
 public:
  SegmentTree(int n) : size_(1) {
    while(size_ < n) size_ <<= 1;
    root_ = new Node();
  }
  void add(int a, int b, int v) {add(a, b + 1, v, root_, 0, size_);}
  int find(int x) {return find(x, root_, 0, size_);}
 private:
  struct Node {
    int value;
    int lazy;
    Node *l_child, *r_child;
  };
  inline void push(Node *n) {
    if(not n->l_child) n->l_child = new Node();
    if(not n->r_child) n->r_child = new Node();
    if(n->lazy) {
      n->l_child->lazy += n->lazy;
      n->r_child->lazy += n->lazy;
      n->value += n->lazy;
      n->lazy = 0;
    }
  }
  void add(int a, int b, int v, Node *n, int l, int r) {
    push(n);
    if(b <= l || r <= a) return;
    if(a <= l && r <= b) {n->lazy = v; return;};
    auto m = (l + r) / 2;
    add(a, b, v, n->l_child, l, m);
    add(a, b, v, n->r_child, m, r);
  }
  int find(int x, Node *n, int l, int r) {
    push(n);
    if(x == l && x == r - 1) return n->value;
    auto m = (l + r) / 2;
    if(x < m) return find(x, n->l_child, l, m);
    else      return find(x, n->r_child, m, r);
  }
  Node *root_;
  int size_;
};

int main() {
  enum Type {Y_IN, X, Y_OUT};
  struct Event {int y; Type type; int x1, x2;};

  int W, H, N;
  cin >> W >> H >> N;

  list<Event> event;
  for(auto i = 0; i < N; ++i) {
    int A, B, C, D;
    cin >> A >> B >> C >> D;
    if(B == D) event.push_back({B, X, A, C});
    else {
      event.push_back({B, Y_IN,  A, C});
      event.push_back({D, Y_OUT, A, C});
    }
  }

  event.push_back({0, X, 0, W});
  event.push_back({0, Y_IN, 0, 0});
  event.push_back({0, Y_IN, W, W});
  event.push_back({H, Y_OUT, 0, 0});
  event.push_back({H, Y_OUT, W, W});
  event.push_back({H, X, 0, W});

  event.sort([](auto l, auto r) {
    if(l.y != r.y) return l.y < r.y;
    if(l.type != r.type) return l.type < r.type;
    if(l.x1 != r.x1) return l.x1 < r.x1;
    return l.x2 < r.x2;
  });

  W += 3;
  for(auto& q: event) {++q.x1; ++q.x2;}

  vector<int> x = {W};
  for(auto& q: event) {
    x.emplace_back(q.x1);
    x.emplace_back(q.x2);
  }
  Compression cx(x);
  for(auto& q: event) {q.x1 = cx.index(q.x1); q.x2 = cx.index(q.x2);}

  SegmentTree flag(cx.index(W));
  UnionFind<int> group;
  int id = 0;
  set<Node> node;
  node.emplace(id, 0, cx.index(W));

  while(!event.empty()) {
//     for(auto i:node)cout<<i.id<<"("<<group.find(i.id)<<")"<<": "<<i.left<<" to "<<i.right<<endl;
//     for(auto i=0;i<W;++i)cout<<" "<<flag.find(i);cout<<endl;cout<<endl;
    auto q = event.front();
    event.pop_front();
    if(q.type == Y_IN) {
//       cout<<"split: "<<q.y<<" "<<q.x1<<" "<<q.x2<<endl;
      auto n = node.upper_bound(q.x1);
      --n;
      if(n->right == q.x1) continue;
      auto f = flag.find(n->left);
      flag.add(n->left, n->right - 1, -f);
      auto i = f ? id + f : n->id;
      id += f + 1;
      group.unite(i, id);
      node.emplace(i, n->left, q.x1);
      node.emplace(id, q.x1, n->right);
      node.erase(n);
    } else if(q.type == Y_OUT) {
//       cout<<"merge: "<<q.y<<" "<<q.x1<<" "<<q.x2<<endl;
      auto l = node.upper_bound(q.x1);
      --l;
      if(q.x1 != l->left) continue;
      auto r = l--;
      auto fl = flag.find(l->left);
      auto fr = flag.find(r->left);
      flag.add(l->left, l->right - 1, -fl);
      flag.add(r->left, r->right - 1, -fr);
      if(fl==0 && fr==0) group.unite(l->id, r->id);
      else if(fl==0)     group.unite(l->id, id + fr);
      else if(fr==0)     group.unite(id + fl, r->id);
      else               group.unite(id + fl, id + fl + fr);
      if(fl==0 && fr==0) node.emplace(l->id, l->left, r->right);
      else               node.emplace(id += fl + fr, l->left, r->right);
      node.erase(l);
      node.erase(r);
    } else {
//       cout<<"separate: "<<q.y<<" "<<q.x1<<" "<<q.x2<<endl;
      auto l = node.upper_bound(q.x1);
      auto r = node.upper_bound(q.x2);
      --l;
      --r;
      if(l->left != q.x1) ++l;
      if(r->right != q.x2) --r;
      if(l == end(node)) continue;
      if(r->right <= l->left) continue;
      flag.add(l->left, r->right - 1, 1);
    }
  }
//   for(auto i:node)cout<<i.id<<"("<<group.find(i.id)<<")"<<": "<<i.left<<" to "<<i.right<<endl;
//   for(auto i=0;i<W;++i)cout<<" "<<flag.find(i);cout<<endl;cout<<endl;
  set<int> res;
  for(auto i = 0; i <= id; ++i) res.emplace(group.find(i));
  cout << res.size() - 1 << endl;
}

Compiler output:
a.cc:1:10: fatal error: windows.h: No such file or directory
    1 | #include <windows.h>
      |          ^~~~~~~~~~~
compilation terminated.