제출 #697416

#제출 시각아이디문제언어결과실행 시간메모리
697416qwerasdfzxclShortcut (IOI16_shortcut)C++17
100 / 100
1832 ms95084 KiB
#include "shortcut.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; constexpr ll INF = 1e17; struct Square{ ll lm, um, lp, up; Square(){lm = lp = -INF, um = -1, up = INF;} void update(ll x, ll y, ll r){ lm = max(lm, x-y-r); um = min(um, x-y+r); lp = max(lp, x+y-r); up = min(up, x+y+r); } void update(ll x, ll r, Square &S){ lm = max(lm, x-r + S.lm); um = min(um, x+r + S.um); lp = max(lp, x-r + S.lp); up = min(up, x+r + S.up); } bool valid(){return lm <= um && lp <= up;} }; int n, I1[1001000], I2[1001000], chk[1001000]; ll X[1001000], a[1001000], c[1001000], d; vector<int> L, R; vector<pair<ll, ll>> ran; bool ok(ll MX){ fill(chk, chk+n+1, 0); ll mx = -INF; L.clear(); R.clear(); for (int i=1;i<=n;i++){ if (mx + X[i] + c[i] > MX) chk[i] |= 2; mx = max(mx, - X[i] + c[i]); } mx = -INF; for (int i=n;i;i--){ if (mx - X[i] + c[i] > MX) chk[i] |= 1; if (chk[i]==3) return 0; mx = max(mx, X[i] + c[i]); } for (int i=1;i<=n;i++) if (chk[I1[i]]&1) L.push_back(I1[i]); for (int i=1;i<=n;i++) if (chk[I2[i]]&2) R.push_back(I2[i]); if (L.empty()) return 1; int b = *max_element(L.begin(), L.end()); for (auto &i:L) a[i] = c[i] + (X[b] - X[i]); for (auto &j:R) a[j] = c[j] + (X[j] - X[b]); int pt = 0; Square s, js; for (auto &i:L){ while(pt<(int)R.size() && a[i] + a[R[pt]] > MX){ js.update(0, X[R[pt]], -c[R[pt]]); pt++; } s.update(X[i], MX - c[i] - d, js); if (!s.valid()) return 0; } ran.clear(); for (int i=1;i<=n;i++){ ran.emplace_back(max(s.lp-X[i], X[i]-s.um), min(s.up-X[i], X[i]-s.lm)); if (ran.back().first > ran.back().second) ran.pop_back(); } if (ran.empty()) return 0; for (int i=0;i<(int)ran.size();i++) if ((i==(int)ran.size()-1) || ran[i].first < ran[i+1].first){ reverse(ran.begin(), ran.begin()+i+1); inplace_merge(ran.begin(), ran.begin()+i+1, ran.end()); break; } ll ss = 0, ee = 0; pt = 2; for (auto &[l, r]:ran){ if (l <= ee) {ee = max(ee, r); continue;} while(pt<=n && X[pt] <= ee){ if (X[pt] >= ss) return 1; ++pt; } ss = l, ee = r; } while(pt<=n && X[pt] <= ee){ if (X[pt] >= ss) return 1; ++pt; } return 0; } bool cmp1(int i, int j){return -X[i]+c[i] < -X[j]+c[j];} bool cmp2(int i, int j){return X[i]+c[i] > X[j]+c[j];} ll naive(int N, std::vector<int> L, std::vector<int> D, int C){ ll ans = INF; for (int i=1;i<N;i++) X[i] = X[i-1] + L[i-1]; for (int i=0;i<N;i++){ for (int j=i+1;j<N;j++){ ll mx = *max_element(D.begin(), D.end()); for (int s=0;s<N;s++){ for (int e=s+1;e<N;e++){ mx = max(mx, min(X[e] - X[s], min(abs(X[j]-X[e]) + abs(X[i]-X[s]) + C, abs(X[j]-X[s]) + abs(X[i] - X[e]) + C)) + D[s] + D[e]); } } ans = min(ans, mx); } } return ans; } long long find_shortcut(int N, std::vector<int> L, std::vector<int> D, int C){ //ll rans = naive(N, L, D, C); L.reserve(N+100); R.reserve(N+100); ran.reserve(N+100); n = N; X[1] = 0; for (int i=1;i<=n;i++) c[i] = D[i-1]; for (int i=2;i<=n;i++) X[i] = X[i-1] + L[i-2]; d = C; for (int i=1;i<=n;i++) I1[i] = i, I2[i] = i; sort(I1+1, I1+n+1, cmp1); sort(I2+1, I2+n+1, cmp2); ll l = *max_element(c+1, c+n+1), r = 1e15 + 100, ans = 1e15 + 100; while(l<=r){ ll mid = (l+r)/2; if (ok(mid)) r = mid-1, ans = mid; else l = mid+1; } //printf("Answer: %lld\n", rans); //printf("Output: %lld\n", ans); //assert(ans == rans); 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...