Submission #212733

#TimeUsernameProblemLanguageResultExecution timeMemory
212733egorlifarMatching (COCI20_matching)C++17
58 / 110
2578 ms40960 KiB
#include <iostream> #include <complex> #include <vector> #include <string> #include <algorithm> #include <cstdio> #include <numeric> #include <cstring> #include <ctime> #include <cstdlib> #include <set> #include <map> #include <unordered_map> #include <unordered_set> #include <list> #include <cmath> #include <bitset> #include <cassert> #include <queue> #include <stack> #include <deque> #include <random> using namespace std; template<typename T1, typename T2>inline void chkmin(T1 &x, T2 y) { if (x > y) x = y; } template<typename T1, typename T2>inline void chkmax(T1 &x, T2 y) { if (x < y) x = y; } #define sz(c) (int)(c).size() #define all(c) (c).begin(), (c).end() #define rall(c) (c).rbegin(), (c).rend() #define left left228 #define right right228 #define rank rank228 #define y1 y1228 #define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin) #define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout) #define files(FILENAME) read(FILENAME), write(FILENAME) #define pb push_back #define mp make_pair using ll = long long; using ld = long double; // const int MAXMEM = 200 * 1000 * 1024; // char _memory[MAXMEM]; // size_t _ptr = 0; // void* operator new(size_t _x) { _ptr += _x; return _memory + _ptr - _x; } // void operator delete (void*) noexcept {} const string FILENAME = "input"; const int MAXN = 100205; int n; int x[MAXN], y[MAXN]; vector<vector<int> > whox, whoy; bool hor[MAXN], ver[MAXN]; int parent[MAXN]; int findset(int a) { if (a == parent[a]) { return a; } return parent[a] = findset(parent[a]); } void unite(int a, int b) { a = findset(a); b = findset(b); if (a == b) { return; } parent[a] = b; } int ss = 1; vector<int> who[MAXN * 7]; struct node { int who = 0; int cntalive = 0; bool odnacomponenta = true; }; node d[MAXN * 8]; node operator +(const node &a, const node &b) { if (!a.cntalive) { return b; } if (!b.cntalive) { return a; } node c; c.cntalive = a.cntalive + b.cntalive; c.who = a.who; c.odnacomponenta = a.odnacomponenta & b.odnacomponenta & (a.who == b.who); return c; } void del(int i) { i += ss; d[i].cntalive = 0; d[i].who = 0; d[i].odnacomponenta = false; while (i >> 1 > 0) { i >>= 1; d[i] = d[i * 2] + d[i * 2 + 1]; } } void change(int i, int comp) { i += ss; d[i].cntalive = 1; d[i].who = comp; d[i].odnacomponenta = true; while (i >> 1 > 0) { i >>= 1; d[i] = d[i * 2] + d[i * 2 + 1]; } } int cur[MAXN * 2]; void tryunite(int v, int vl, int vr, int l, int r, int x) { if (!d[v].cntalive) { return; } if (vl > r || vr < l) { return; } if (l <= vl && vr <= r) { // cout << "opa" << ' ' << vl << ' ' << vr << endl; if (d[v].odnacomponenta) { // cout << "kek" << endl; int t = findset(x); if (t != x) { int b= findset(d[v].who); // cout << x << ' ' << t << ' ' << b << endl; if (t != b) { int g = sz(who[t]); int g1 = sz(who[b]); int a = t; if (g < g1) { swap(a, b); } parent[b] = a; //cout << a << ' ' << b << endl; for (auto x: who[b]) { if (cur[x] != -1 && findset(cur[x]) == a) { who[a].pb(x); change(x, a); } } who[b].clear(); who[b].shrink_to_fit(); } } else { parent[x] = findset(d[v].who); } } else { tryunite(v * 2, vl, (vl + vr) / 2, l, r, x); tryunite(v * 2 + 1, (vl + vr) / 2 + 1, vr, l, r, x); } return; } tryunite(v * 2, vl, (vl + vr) / 2, l, r, x); tryunite(v * 2 + 1, (vl + vr) / 2 + 1, vr, l, r, x); } int valh[MAXN], valv[MAXN]; vector<pair<pair<int, int>, int> > fs[MAXN]; vector<pair<pair<int, int>, int> > mx[MAXN]; int cnt[MAXN][2]; int col[MAXN]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); // read(FILENAME); cin >> n; whox.resize(100001); whoy.resize(100001); for (int i = 0; i < n; i++) { cin >> x[i] >> y[i]; whox[x[i]].pb(i); whoy[y[i]].pb(i); parent[i] = i; } vector<pair<int, int> > vs, hs; for (auto xx: whox) { if (sz(xx) == 2) { for (auto y: xx) { ver[y] = true; valv[y] = xx[0] ^ xx[1]; } unite(xx[0], xx[1]); if (y[xx[0]] > y[xx[1]]) { swap(xx[0], xx[1]); } int t = findset(xx[0]); fs[y[xx[0]]].pb({mp(x[xx[0]], t), 1}); fs[y[xx[1]]].pb({mp(x[xx[0]], t), -1}); } } for (auto xx: whoy) { if (sz(xx) == 2) { for (auto y: xx) { hor[y] = true; valh[y] = xx[0] ^ xx[1]; } unite(xx[0], xx[1]); int t = findset(xx[0]); mx[y[xx[0]]].pb(mp(mp(x[xx[0]], x[xx[1]]), t)); } } for (int i = 0; i < n; i++) { if (!ver[i] && !hor[i]) { cout << "NE\n"; exit(0); } } ss = 1; while (ss <= 100000) { ss <<= 1; } for (int i = 0; i <= 100000; i++) { for (auto x: fs[i]) { if (x.second == -1) { // who[findset(cur[x.first.first])].erase(x.first.first); cur[x.first.first] = -1; del(x.first.first); } } for (auto x: fs[i]) { if (x.second == 1) { cur[x.first.first] = x.first.second; who[x.first.second].pb(x.first.first); change(x.first.first, x.first.second); } } for (auto x: mx[i]) { int l = x.first.first; int r = x.first.second; if (l > r) { swap(l, r); } tryunite(1, 1, ss, l + 1, r + 1, x.second); } } for (int i = 0; i < n; i++) { if (!ver[i]) { cnt[findset(i)][1]++; } if (!hor[i]) { cnt[findset(i)][0]++; } } for (int i = 0; i < n; i++) { if (findset(i) == i) { if (cnt[i][0] && cnt[i][1]) { cout << "NE\n"; return 0; } col[i] = cnt[i][0] ? 0: 1; } } cout << "DA\n"; for (int i = 0; i < n; i++) { int t = col[findset(i)]; int f = 0; if (t == 0) { f = valv[i] ^ i; } else { f = valh[i] ^ i; } if (f > i) { assert(i != f); cout << i + 1 << ' ' << f + 1 << '\n'; } } return 0; }
#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...