제출 #290353

#제출 시각아이디문제언어결과실행 시간메모리
290353MarcoMeijerSky Walking (IOI19_walk)C++14
100 / 100
2360 ms134444 KiB
#include <bits/stdc++.h> #include "walk.h" using namespace std; //macros typedef long long ll; typedef pair<int, int> ii; typedef pair<ll, ll> lll; typedef tuple<int, int, int> iii; typedef vector<int> vi; typedef vector<ii> vii; typedef vector<iii> viii; typedef vector<ll> vll; typedef vector<lll> vlll; #define REP(a,b,c) for(int a=int(b); a<int(c); a++) #define RE(a,c) REP(a,0,c) #define RE1(a,c) REP(a,1,c+1) #define REI(a,b,c) REP(a,b,c+1) #define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--) #define FOR(a,b) for(auto& a:b) #define INF 1e18 #define pb push_back #define fi first #define se second #define sz size() #define all(a) a.begin(), a.end() ll min_distance(vi x, vi h, vi l, vi r, vi y, int s, int g) { int n=x.sz, m=l.sz, N=0; // change graph RE(j,2) { int x = j ? s : g; vi nl, nr, ny; viii pq; RE(i,n) pq.pb({h[i],2,i}); RE(i,m) { if(l[i] < x && x < r[i]) { pq.pb({y[i],1,i}); } else { nl.pb(l[i]); nr.pb(r[i]); ny.pb(y[i]); } } int mostL = -1e9, mostR = 1e9; sort(all(pq), greater<iii>()); FOR(p,pq) { int y, t, i; tie(y,t,i) = p; if(t == 2) { if(i <= x) mostL = max(mostL, i); if(i >= x) mostR = min(mostR, i); } else if(t == 1) { if(mostL != l[i] ) nl.pb(l[i]) , nr.pb(mostL), ny.pb(y); if(mostL != mostR) nl.pb(mostL), nr.pb(mostR), ny.pb(y); if(r[i] != mostR) nl.pb(mostR), nr.pb(r[i]) , ny.pb(y); } } l=nl; r=nr; y=ny; m = l.sz; } l.pb(s); r.pb(s); y.pb(0); l.pb(g); r.pb(g); y.pb(0); m = l.sz; // coördinate compression map<int,int> compY; int difY=0; { set<int> st; RE(i,m) st.insert(y[i]); FOR(y,st) compY[y]=difY++; } ll ans = INF; map<ii, int> vertexes; vector<vi> horVertex; horVertex.resize(difY); vector<vii> adj; auto getVert = [&](int x, int y) { if(vertexes.count({x,y})) return vertexes[{x,y}]; horVertex[compY[y]].pb(x); return vertexes[{x,y}] = N++; }; auto connect = [&](ii a, ii b) { int u = getVert(a.fi, a.se); int v = getVert(b.fi, b.se); int d = abs(a.fi-b.fi)+abs(a.se-b.se); adj[u].pb({v,d}); adj[v].pb({u,d}); }; adj.resize(m*4); // create vertexes, and vertical edges { viii pq; multiset<int> st; RE(i,m) pq.pb({r[i],2,i}); RE(i,m) pq.pb({l[i],1,i}); RE(i,m) pq.pb({r[i],1,i}); RE(i,m) pq.pb({l[i],0,i}); sort(all(pq), greater<iii>()); FOR(p,pq) { int cx, t, i; tie(cx,t,i) = p; if(t == 2) { // right st.insert(y[i]); } else if(t == 1) { // connect getVert(x[cx], y[i]); auto it = st.lower_bound(y[i]); if(it != st.begin()) --it, connect({x[cx],y[i]}, {x[cx],*it}); } else { // left st.erase(st.find(y[i])); } } } // create horizontal edges { FOR(f,horVertex) sort(all(f)); RE(i,m) { if(l[i] == r[i]) continue; vi& f = horVertex[compY[y[i]]]; auto it=lower_bound(all(f), x[l[i]]); auto ed=upper_bound(all(f), x[r[i]]); while(1) { auto prev = it++; if(it == ed) break; connect({*prev, y[i]}, {*it, y[i]}); } } } // dijkstra { vll dist; dist.assign(N, INF); priority_queue<lll,vlll,greater<lll>> pq; dist[getVert(x[s],0)] = 0; pq.push({0, getVert(x[s],0)}); int ed = getVert(x[g],0); while(!pq.empty()) { lll p = pq.top(); pq.pop(); int u=p.se; ll d=p.fi; if(dist[u] != d) continue; if(u == ed) break; FOR(p,adj[u]) { int v = p.fi; ll add = p.se; if(d+add < dist[v]) { dist[v] = d+add; pq.push({dist[v],v}); } } } ans = dist[ed]; } if(ans == INF) ans = -1; return ans; }
#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...