제출 #1225943

#제출 시각아이디문제언어결과실행 시간메모리
1225943Hamed_GhaffariSky Walking (IOI19_walk)C++20
25 / 100
493 ms141344 KiB
#include "walk.h" #include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; #define X first #define Y second #define lc id<<1 #define rc lc|1 #define mid ((l+r)>>1) const int MXN = 1e5+5; const ll inf = 1e18; namespace sub4 { int n, m, ord[MXN], pos[MXN]; ll dis[MXN]; vector<int> y, op[MXN], cl[MXN]; ll seg[MXN<<2][2]; void build(int l=0, int r=m, int id=1) { seg[id][0] = seg[id][1] = inf*2; if(r-l == 1) return; build(l, mid, lc); build(mid, r, rc); } void upd(int p, bool x, int l=0, int r=m, int id=1) { if(r-l == 1) { if(x) seg[id][0] = dis[ord[l]]+y[ord[l]], seg[id][1] = dis[ord[l]]-y[ord[l]]; else seg[id][0] = seg[id][1] = inf*2; return; } p<mid ? upd(p, x, l, mid, lc) : upd(p, x, mid, r, rc); seg[id][0] = min(seg[lc][0], seg[rc][0]); seg[id][1] = min(seg[lc][1], seg[rc][1]); } ll get(int s, int e, bool x, int l=0, int r=m, int id=1) { if(s>=r || l>=e) return inf*2; if(s<=l && r<=e) return seg[id][x]; return min(get(s, e, x, l, mid, lc), get(s, e, x, mid, r, rc)); } ll min_distance(vector<int> x, vector<int> h, vector<int> l, vector<int> r, vector<int> y, int s, int g) { n = x.size(); m = y.size(); sub4::y = y; iota(ord, ord+m, 0); sort(ord, ord+m, [&](int i, int j) { return y[i]<y[j]; }); for(int i=0; i<m; i++) pos[ord[i]] = i; build(); for(int i=0; i<m; i++) { op[l[i]].push_back(i); if(r[i]+1<n) cl[r[i]+1].push_back(i); } for(int i : op[0]) { dis[i] = y[i]; upd(pos[i], 1); } for(int i=1; i<n; i++) { for(int j : cl[i]) upd(pos[j], 0); for(int j : op[i]) { int lb=-1, rb=m, mb; while(rb-lb>1) { mb = (lb+rb)>>1; (y[ord[mb]]>h[i] ? rb : lb) = mb; } dis[j] = min(get(pos[j], rb, 0)-y[j], get(0, pos[j]+1, 1)+y[j]); upd(pos[j], 1); } } int lb=-1, rb=m, mb; while(rb-lb>1) { mb = (lb+rb)>>1; (y[ord[mb]]>h[n-1] ? rb : lb) = mb; } ll ans = get(0, rb, 0); if(ans>=inf) return -1; return ans + x[n-1] - x[0]; } } int ordn[MXN], ordm[MXN], N; vector<pii> vec[MXN]; vector<pii> G[MXN*23]; ll dis[MXN*23]; inline void add(int u, int v, int w) { G[u].push_back({v, w}); G[v].push_back({u, w}); } ll min_distance(vector<int> x, vector<int> h, vector<int> l, vector<int> r, vector<int> y, int s, int g) { if(s==0 && g==x.size()-1) return sub4::min_distance(x, h, l, r, y, s, g); int n = x.size(), m = y.size(); iota(ordn, ordn+n, 0); sort(ordn, ordn+n, [&](int i, int j) { return h[i]>h[j]; }); iota(ordm, ordm+m, 0); sort(ordm, ordm+m, [&](int i, int j) { return y[i]>y[j]; }); int ptr=0; set<int> st; for(int i=0; i<m; i++) { while(ptr<n && h[ordn[ptr]]>=y[ordm[i]]) st.insert(ordn[ptr++]); int lst = -1, id = -1; for(auto it = st.lower_bound(l[ordm[i]]); it!=st.end() && (*it)<=r[ordm[i]]; it++) { if(lst != -1) add(id, N, x[*it]-x[lst]); lst = *it; id = N; vec[*it].push_back({N++, y[ordm[i]]}); } } vec[s].push_back({N++, 0}); vec[g].push_back({N++, 0}); for(int i=0; i<n; i++) for(int j=1; j<vec[i].size(); j++) add(vec[i][j-1].X, vec[i][j].X, vec[i][j-1].Y-vec[i][j].Y); fill(dis, dis+N, inf); priority_queue<pll> pq; pq.push({dis[N-2]=0, N-2}); while(!pq.empty()) { ll d = -pq.top().X; int v = pq.top().Y; pq.pop(); if(d!=dis[v]) continue; for(auto [u, w] : G[v]) if(dis[u]>d+w) pq.push({-(dis[u]=d+w), u}); } return dis[N-1] >= inf ? -1 : dis[N-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...