Submission #565707

#TimeUsernameProblemLanguageResultExecution timeMemory
565707kartelFountain Parks (IOI21_parks)C++17
100 / 100
2968 ms177756 KiB
#include <bits/stdc++.h> //#include "grader.cpp" #include "parks.h" #define F first #define S second #define pb push_back #define sz(x) (int)x.size() #define el "\n" #define all(x) (x).begin(), (x).end() //#pragma GCC optimize("unroll-loops") //#pragma GCC optimize("-O3") //#pragma GCC optimize("Ofast") using namespace std; typedef long long ll; const int N = 5e5 + 500; mt19937 rnd(time(0)); const int steps[4][2] = {{0, 2}, {2, 0}, {0, -2}, {-2, 0}}; const int dsteps[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; map <pair <int, int>, pair <int, int> > road; pair <int, int> block[N * 2]; int pr[N]; int cmp[2 * N], to[2 * N]; vector <int> g[2 * N], gr[2 * N], ord; bool mk[2 * N]; int f(int v) {return (pr[v] == v ? v : pr[v] = f(pr[v]));} void link(int v, int u) { v = f(v); u = f(u); if (v == u) { return; } pr[u] = v; } int nt(int x) {return (x < N ? x + N : x - N);} void add_impl(int a, int b) { int na = nt(a), nb = nt(b); g[na].pb(b); gr[b].pb(na); g[nb].pb(a); gr[a].pb(nb); } void dfs(int v) { mk[v] = 1; for (auto u : g[v]) { if (mk[u]) { continue; } dfs(u); } ord.pb(v); } vector <pair <int, int> > pts; void dfsd(int v) { mk[v] = 1; for (auto u : g[v]) { if (mk[u]) { continue; } int dx = pts[v].F - pts[u].F; int dy = pts[v].S - pts[u].S; block[u] = road[{dx, dy}]; dfsd(u); } } void get_erased_2x2(vector <int> &x, vector <int> &y, map<pair <int, int>, int> &del) { map <pair <int, int>, int> cnt, who; for (int i = 0; i < sz(x); i++) { who[{x[i], y[i]}] = i; for (int j = 0; j < 4; j++) { int cx = x[i] + dsteps[j][0]; int cy = y[i] + dsteps[j][1]; cnt[{cx, cy}]++; if (cnt[{cx, cy}] == 4) { pts.pb({cx, cy}); } } } sort(all(pts)); cnt.clear(); int ptr = 0; for (auto &[x, y] : pts) { cnt[{x, y}] = ptr++; } ptr = 0; for (auto &[x, y] : pts) { int par = (x / 2 + y / 2) % 2; for (int i = 0; i < 2; i++) { int cx = x + steps[i * 2 + par][0]; int cy = y + steps[i * 2 + par][1]; if (!cnt.count({cx, cy})) { continue; } g[cnt[{cx, cy}]].pb(ptr); } ptr++; } for (int i = 0; i < sz(pts); i++) { if (mk[i]) { continue; } int par = (pts[i].F / 2 + pts[i].S / 2) & 1; if (par & 1) { block[i] = road[{-2, 0}]; } else { block[i] = road[{0, -2}]; } queue <int> q; q.push(i); mk[i] = 1; while (sz(q)) { int v = q.front(); q.pop(); for (auto u : g[v]) { if (mk[u]) { continue; } int dx = pts[v].F - pts[u].F; int dy = pts[v].S - pts[u].S; block[u] = road[{dx, dy}]; q.push(u); mk[u] = 1; } } } for (int i = 0; i < sz(pts); i++) { auto [x, y] = pts[i]; auto [a, b] = block[i]; int v = who[{x + dsteps[a][0], y + dsteps[a][1]}]; int u = who[{x + dsteps[b][0], y + dsteps[b][1]}]; del[{v, u}] = del[{u, v}] = 1; } } int construct_roads(vector <int> x, vector <int> y) { int n = sz(x); road[{0, 2}] = {2, 0}; road[{2, 0}] = {0, 1}; road[{0, -2}] = {1, 3}; road[{-2, 0}] = {3, 2}; map <pair <int, int>, int> mp; vector <pair <int, int> > r; map <pair <int, int>, int> del; vector <int> pm(n); iota(all(pm), 0); shuffle(all(pm), rnd); bool sd = 1; for (int i = 0; i < n; i++) { mp[{x[i], y[i]}] = i; pr[i] = i; sd &= (x[i] >= 2 && x[i] <= 4); } get_erased_2x2(x, y, del); for (auto i : pm) { for (int j = 0; j < 4; j++) { int cx = x[i] + steps[j][0]; int cy = y[i] + steps[j][1]; if (mp.count({cx, cy}) && f(i) != f(mp[{cx, cy}])) { int to = mp[{cx, cy}]; if (del[{i, to}]) { continue; } link(i, to); r.pb({i, to}); } } } sort(all(r)); r.resize(unique(all(r)) - r.begin()); for (int i = 0; i < n; i++) { if (f(i) != f(0)) { return 0; } } vector <int> u, v, A, B; map <pair <int, int>, vector <int> > e; for (int i = 0; i < sz(r); i++) { int a = r[i].F, b = r[i].S; u.pb(a); v.pb(b); if (abs(x[a] - x[b]) == 0) { int lx = x[a]; int ly = min(y[a], y[b]); e[{lx - 1, ly + 1}].pb(i); e[{lx + 1, ly + 1}].pb(nt(i)); } else { int lx = min(x[a], x[b]); int ly = y[a]; e[{lx + 1, ly + 1}].pb(i); e[{lx + 1, ly - 1}].pb(nt(i)); } } for (int i = 0; i < 2 * N; i++) { mk[i] = 0; g[i].clear(); } for (auto [p, v] : e) { int x = p.F, y = p.S; if (sz(v) == 1) { continue; } for (auto a : v) { for (auto b : v) { if (a == b) { continue; } add_impl(a, b); } } } for (int i = 0; i < 2 * N; i++) { cmp[i] = -1; if (mk[i]) { continue; } dfs(i); } reverse(all(ord)); int C = 0; for (auto v : ord) { function <void(int)> dfsr = [&](int v) { if (cmp[v] != -1) { return; } cmp[v] = C; for (auto u : gr[v]) { dfsr(u); } }; dfsr(v); C++; } for (int i = 0; i < N; i++) { if (cmp[i] == cmp[nt(i)]) { return 0; } to[i] = (cmp[i] > cmp[nt(i)]); } for (int i = 0; i < sz(r); i++) { int a = r[i].F, b = r[i].S; if (abs(x[a] - x[b]) == 0) { int lx = x[a]; int ly = min(y[a], y[b]); if (to[i]) { A.pb(lx + 1); } else { A.pb(lx - 1); } B.pb(ly + 1); } else { int lx = min(x[a], x[b]); int ly = y[a]; if (to[i]) { B.pb(ly - 1); } else { B.pb(ly + 1); } A.pb(lx + 1); } } build(u, v, A, B); return 1; }

Compilation message (stderr)

parks.cpp: In function 'int construct_roads(std::vector<int>, std::vector<int>)':
parks.cpp:222:13: warning: unused variable 'x' [-Wunused-variable]
  222 |         int x = p.F, y = p.S;
      |             ^
parks.cpp:222:22: warning: unused variable 'y' [-Wunused-variable]
  222 |         int x = p.F, y = p.S;
      |                      ^
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...