Submission #1040988

#TimeUsernameProblemLanguageResultExecution timeMemory
1040988Dan4LifeFountain Parks (IOI21_parks)C++17
100 / 100
240 ms84308 KiB
#include "parks.h" #include <bits/stdc++.h> using namespace std; #define pb push_back #define sz(a) (int)a.size() #define all(a) begin(a),end(a) using vi = vector<int>; using ll = long long; using ar2 = array<int,2>; using ar3 = array<int,3>; const int mxN = (int)2e5+10; int n; struct Edge{ int fa, fb, x, y; Edge(int a=0, int b=0, int _x=-1, int _y=-1){ fa=a, fb=b, x=_x, y=_y; } }; vector<Edge> edges; vector<ar3> fountains, origFountains; vector<int> adj[mxN]; set<ar2> usedB, S[mxN]; template<int SZ> struct DSU{ int p[SZ]; vector<int> comp[SZ]; void init(int n){ for(int i = 0; i < n; i++){ p[i]=i; comp[i].clear(); comp[i].pb(i); } } int findSet(int i){return p[i]==i?i:p[i]=findSet(p[i]);} bool isSameSet(int i, int j) {return findSet(i)==findSet(j);} void unionSet(int i, int j){ adj[i].pb(j); adj[j].pb(i); int x = findSet(i), y = findSet(j); if(x==y) return; if(sz(comp[x]) < sz(comp[y])) swap(x,y); p[y]=x; for(auto u : comp[y]) comp[x].pb(u); } int findSz(int i) { return sz(comp[findSet(i)]); } }; DSU<mxN> dsu; int construct_roads(vi x, vi y) { n = sz(x); dsu.init(n); if (n==1){ build({}, {}, {}, {}); return 1; } for(int i = 0; i < n; i++){ fountains.pb({x[i],y[i],i}); origFountains.pb({x[i],y[i],i}); } sort(all(fountains),[&](ar3 a, ar3 b){ if(a[0]!=b[0]) return a[0]<b[0]; return a[1]<b[1]; }); for(int i = sz(fountains)-1; i>=0; i--) S[fountains[i][0]].insert({fountains[i][1], fountains[i][2]}); for(int i = 1; i < sz(fountains); i++){ if(fountains[i][0]!=fountains[i-1][0]) continue; if(fountains[i][1]-fountains[i-1][1]==2){ auto [x1,y1,a] = fountains[i-1]; auto [x2,y2,b] = fountains[i]; dsu.unionSet(a,b); } } for(int i = 0; i < sz(fountains); i++){ auto [x1,y1,a] = fountains[i]; auto itr = S[x1+2].lower_bound({y1,-1}); if(itr==end(S[x1+2]) or (*itr)[0]!=y1) continue; int b = (*itr)[1]; dsu.unionSet(a,b); } if(dsu.findSz(0)!=n) return 0; for(auto [x1,y1,i] : fountains){ int choice = ((x1+y1)%4==0); for(auto j : adj[i]){ auto [x2,y2,_] = origFountains[j]; int ver = 0; if(x1==x2){ if(y1>y2) continue; ver = 1; } else if(x1>x2) continue; if(choice){ if(ver){ if(!usedB.count({x1+1,y1+1})){ usedB.insert({x1+1,y1+1}); edges.pb(Edge(i,j,x1+1,y1+1)); } } else{ if(!usedB.count({x1+1,y1-1})){ usedB.insert({x1+1,y1-1}); edges.pb(Edge(i,j,x1+1,y1-1)); } } } else{ if(ver){ if(!usedB.count({x1-1,y1+1})){ usedB.insert({x1-1,y1+1}); edges.pb(Edge(i,j,x1-1,y1+1)); } } else{ if(!usedB.count({x1+1,y1+1})){ usedB.insert({x1+1,y1+1}); edges.pb(Edge(i,j,x1+1,y1+1)); } } } } } vi U, V, A, B; for(auto edge : edges){ U.pb(edge.fa), V.pb(edge.fb); A.pb(edge.x), B.pb(edge.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...