Submission #438128

#TimeUsernameProblemLanguageResultExecution timeMemory
438128gs14004Fountain Parks (IOI21_parks)C++17
70 / 100
727 ms80620 KiB
#include "parks.h" #include <bits/stdc++.h> #define sz(v) ((int)(v).size()) #define all(v) (v).begin(), (v).end() using namespace std; using lint = long long; using pi = pair<lint, lint>; const int MAXN = 400005; const int mod = 1e9 + 7; const int dx[4] = {1, 0, -1, 0}; const int dy[4] = {0, 1, 0, -1}; struct point{ int x, y, idx; }; struct disj{ int pa[MAXN]; void init(int n){ iota(pa, pa + n, 0); } int find(int x){ return pa[x] = (pa[x] == x ? x : find(pa[x])); } bool uni(int p, int q){ p = find(p); q = find(q); if(p == q) return 0; pa[q] = p; return 1; } }disj; bool vis[MAXN]; int V = 0, E = 0; vector<int> dfn; vector<pi> gph[MAXN]; void dfs(int x){ if(vis[x]) return; vis[x] = 1; dfn.push_back(x); V += 1; E += sz(gph[x]); for(auto &[_, y] : gph[x]) dfs(y); } int construct_roads(std::vector<int> x, std::vector<int> y) { int n = sz(x); vector<point> p; vector<pi> edges; vector<pi> matches; vector<pi> to_mst; auto get_mode = [&](pi q){ int x = q.first, y = q.second; int val = (p[y].x + p[y].y) % 4; if(val % 4 == 0) return p[x].x == p[y].x ? 0 : 2; return p[x].x == p[y].x ? 1 : 3; }; for(int i = 0; i < n; i++){ p.push_back({x[i], y[i], i}); } sort(all(p), [&](const point &a, const point &b){ return pi(a.x, a.y) < pi(b.x, b.y); }); disj.init(n); for(int i = 1; i < sz(p); i++){ if(p[i-1].x == p[i].x && p[i-1].y + 2 == p[i].y){ to_mst.emplace_back(p[i-1].idx, p[i].idx); } } sort(all(p), [&](const point &a, const point &b){ return pi(a.y, a.x) < pi(b.y, b.x); }); for(int i = 1; i < sz(p); i++){ if(p[i-1].y == p[i].y && p[i-1].x + 2 == p[i].x){ to_mst.emplace_back(p[i-1].idx, p[i].idx); } } sort(all(p), [&](const point &a, const point &b){ return a.idx < b.idx; }); sort(all(to_mst), [&](const pi &x, const pi &y){ return get_mode(x) < get_mode(y); }); for(auto &[x, y] : to_mst){ if(disj.uni(x, y)) edges.emplace_back(x, y); } if(sz(edges) != n - 1) return 0; map<pi, int> mp; vector<int> U, _V, A(n-1), B(n-1); for(auto &[x, y] : edges){ U.push_back(x); _V.push_back(y); set<pi> s; int mx = (p[x].x + p[y].x) / 2; int my = (p[x].y + p[y].y) / 2; for(int i = 0; i < 4; i++){ s.emplace(mx + dx[i], my + dy[i]); } s.erase(pi(p[x].x, p[x].y)); s.erase(pi(p[y].x, p[y].y)); for(auto &p : s){ if(mp.find(p) == mp.end()){ int idx = sz(mp); mp[p] = idx; } } matches.emplace_back(mp[*s.begin()], mp[*s.rbegin()]); } vector<int> deg(sz(mp)); for(int i = 0; i < sz(matches); i++){ int x, y; tie(x, y) = matches[i]; gph[x].emplace_back(i, y); gph[y].emplace_back(i, x); deg[x]++; deg[y]++; } vector<pi> mrev(sz(mp)); for(auto &[x, y] : mp){ mrev[y] = x; } for(int i = 0; i < sz(mp); i++){ if(!vis[i]){ V = E = 0; dfn.clear(); dfs(i); E /= 2; if(V < E){ return 0; } assert(V >= E); queue<int> que; for(auto &v : dfn){ if(deg[v] == 1){ que.push(v); } } while(sz(que)){ int x = que.front(); que.pop(); for(auto &[i, y] : gph[x]){ if(!deg[y]) continue; deg[x]--; deg[y]--; A[i] = mrev[x].first; B[i] = mrev[x].second; // printf("%d %d\n", i, x); if(deg[y] == 1){ que.push(y); } } } if(V != E) continue; for(auto &v : dfn){ if(deg[v] == 2){ int I, V, W; for(auto &[i, w] : gph[v]){ if(deg[w] == 2){ deg[v]--; deg[w]--; tie(I, V, W) = make_tuple(i, v, w); break; } } gph[V].erase(find(all(gph[V]), pi(I, W))); gph[W].erase(find(all(gph[W]), pi(I, V))); // printf("%d %d\n", I, W); A[I] = mrev[W].first; B[I] = mrev[W].second; que.push(V); break; } } while(sz(que)){ int x = que.front(); que.pop(); for(auto &[i, y] : gph[x]){ if(!deg[y]) continue; deg[x]--; deg[y]--; // printf("%d %d\n", i, x); A[i] = mrev[x].first; B[i] = mrev[x].second; if(deg[y] == 1){ que.push(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...