Submission #1068811

#TimeUsernameProblemLanguageResultExecution timeMemory
1068811BoasFountain Parks (IOI21_parks)C++17
70 / 100
394 ms69828 KiB
#include "parks.h" // #pragma GCC optimize("trapv") #include <bits/stdc++.h> using namespace std; typedef vector<int> vi; typedef long long ll; typedef vector<signed> vi32; typedef vector<bool> vb; typedef vector<vi> vvi; typedef unordered_set<ll> si; typedef pair<int, int> ii; typedef tuple<int, int, int> iii; typedef vector<ii> vii; typedef set<iii> siii; // typedef unordered_set<ii> sii; typedef vector<vii> vvii; #define pb push_back #define loop(x, i) for (int i = 0; i < x; i++) #define ALL(x) begin(x), end(x) #define sz(x) (int)x.size() vii adj = {{-2, 0}, {2, 0}, {0, 2}, {0, -2}}; vector<si> benchPoints(4); // neighbour count ll MX = 200'004; ll toInt(ii p) { auto [b, c] = p; return MX * b + c; } void addNeighbour(ll x, ll y, int dif = 1) { if (benchPoints[1].count(toInt({x, y}))) { benchPoints[1].erase(toInt({x, y})); if (dif == 1) { benchPoints[2].insert(toInt({x, y})); } } else if (benchPoints[2].count(toInt({x, y}))) { benchPoints[2].erase(toInt({x, y})); benchPoints[2 + dif].insert(toInt({x, y})); } else if (benchPoints[3].count(toInt({x, y}))) { benchPoints[3].erase(toInt({x, y})); if (dif == 1) throw; benchPoints[2].insert(toInt({x, y})); } else if (dif == 1) { benchPoints[1].insert(toInt({x, y})); } } int construct_roads(vi xs, vi ys) { unordered_map<ll, int> fountains; unordered_map<ll, int> roads; // unordered_set<ii> gotBench; int n = sz(xs); loop(n, i) { fountains[toInt({xs[i], ys[i]})] = i; } vb vis(n); vi u, v, a, b; a = b = vi(n - 1); int visCnt = 1; auto dfs = [&](auto &&self, int i) -> void { int x = xs[i], y = ys[i]; for (const auto &[dx, dy] : adj) { ii pos = {x + dx, y + dy}; if (fountains.count(toInt(pos))) { int j = fountains[toInt(pos)]; if (vis[j]) continue; if (dx != 0) { roads[toInt({x + dx / 2, y})] = sz(u); addNeighbour(x + dx / 2, y + 1); addNeighbour(x + dx / 2, y - 1); } else { roads[toInt({x, y + dy / 2})] = sz(u); addNeighbour(x + 1, y + dy / 2); addNeighbour(x - 1, y + dy / 2); } u.pb(i); v.pb(j); vis[j] = 1; visCnt++; self(self, j); } } }; vis[0] = 1; dfs(dfs, 0); if (visCnt != n) return 0; assert(sz(u) == n - 1); for (int benchesBuilt = 0; benchesBuilt < sz(u); benchesBuilt++) { ll x = -1, y = -1; for (int i = 1; i <= 3; i++) { if (!benchPoints[i].empty()) { ll pr = *benchPoints[i].begin(); x = pr / MX, y = pr % MX; benchPoints[i].erase(benchPoints[i].begin()); break; } } if (x == -1) break; ii loc; if (roads.count(toInt({x + 1, y}))) { loc = {x + 1, y}; addNeighbour(x + 2, y, -1); } else if (roads.count(toInt({x - 1, y}))) { loc = {x - 1, y}; addNeighbour(x - 2, y, -1); } else if (roads.count(toInt({x, y + 1}))) { loc = {x, y + 1}; addNeighbour(x, y + 2, -1); } else if (roads.count(toInt({x, y - 1}))) { loc = {x, y - 1}; addNeighbour(x, y - 2, -1); } else throw; int ix = roads[toInt(loc)]; roads.erase(toInt(loc)); a[ix] = x; b[ix] = y; } build(u, v, a, b); return 1; }
#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...