Submission #227319

#TimeUsernameProblemLanguageResultExecution timeMemory
227319abekerMatching (COCI20_matching)C++17
110 / 110
967 ms104332 KiB
#include <bits/stdc++.h> using namespace std; typedef pair <int, int> pii; const int MAXN = 1e5 + 5; const int offset = 1 << 17; struct Segment { int x1, y1, x2, y2; }; class Tournament { set <pii> S[2 * offset]; public: void update(int x, int lo, int hi, int from, int to, pii p) { if (lo >= to || hi <= from) return; if (lo >= from && hi <= to) { S[x].insert(p); return; } int mid = (lo + hi) / 2; update(2 * x, lo, mid, from, to, p); update(2 * x + 1, mid, hi, from, to, p); } vector <int> query(int x, int from, int to) { vector <int> res; for (x += offset; x; x /= 2) while (1) { auto it = S[x].lower_bound({from, 0}); if (it == S[x].end() || it->first > to) break; res.push_back(it->second); S[x].erase(it); } return res; } }; int N; int x[MAXN], y[MAXN]; vector <int> adj[MAXN]; vector <int> hor[MAXN], ver[MAXN]; vector <Segment> all; vector <pii> edges; Tournament Hor, Ver; int clr[2 * MAXN]; queue <int> Q; void load() { scanf("%d", &N); for (int i = 0; i < N; i++) { scanf("%d%d", x + i, y + i); ver[x[i]].push_back(i); hor[y[i]].push_back(i); } } void bye() { puts("NE"); exit(0); } void process(const vector <int> &v, int c) { for (auto it : v) { if (clr[it] == -1) clr[it] = c; else if (clr[it] != c) bye(); Q.push(it); } } void other(int pt, int seg) { if (adj[pt].size() == 1) bye(); process({adj[pt][0] ^ adj[pt][1] ^ seg}, 1); } void horizontal(int id) { if (clr[id]) process(Ver.query(all[id].y1, all[id].x1, all[id].x2), 0); else { other(edges[id].first, id); other(edges[id].second, id); } } void vertical(int id) { if (clr[id]) process(Hor.query(all[id].x1, all[id].y1, all[id].y2), 0); else { other(edges[id].first, id); other(edges[id].second, id); } } inline bool is_hor(int id) { return all[id].y1 == all[id].y2; } void solve() { memset(clr, -1, sizeof clr); for (int i = 1; i < MAXN; i++) { if (hor[i].size() == 2) { int mn = MAXN, mx = 0; for (auto it : hor[i]) { adj[it].push_back(all.size()); mn = min(mn, x[it]); mx = max(mx, x[it]); } Hor.update(1, 0, offset, mn, mx + 1, {i, all.size()}); edges.push_back({hor[i][0], hor[i][1]}); all.push_back({mn, i, mx, i}); } if (ver[i].size() == 2) { int mn = MAXN, mx = 0; for (auto it : ver[i]) { adj[it].push_back(all.size()); mn = min(mn, y[it]); mx = max(mx, y[it]); } Ver.update(1, 0, offset, mn, mx + 1, {i, all.size()}); edges.push_back({ver[i][0], ver[i][1]}); all.push_back({i, mn, i, mx}); } } for (int i = 0; i < N; i++) if (adj[i].empty()) bye(); else if (adj[i].size() == 1) { clr[adj[i][0]] = 1; Q.push(adj[i][0]); } while (!Q.empty()) { int curr = Q.front(); Q.pop(); if (is_hor(curr)) horizontal(curr); else vertical(curr); } puts("DA"); for (int i = 0; i < all.size(); i++) { if (clr[i] == -1) clr[i] = is_hor(i); if (clr[i]) printf("%d %d\n", ++edges[i].first, ++edges[i].second); } } int main() { load(); solve(); return 0; }

Compilation message (stderr)

matching.cpp: In function 'void solve()':
matching.cpp:149:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < all.size(); i++) {
                  ~~^~~~~~~~~~~~
matching.cpp: In function 'void load()':
matching.cpp:52:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &N);
  ~~~~~^~~~~~~~~~
matching.cpp:54:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", x + i, y + i);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...