Submission #1051583

#TimeUsernameProblemLanguageResultExecution timeMemory
1051583Alihan_8Shortcut (IOI16_shortcut)C++17
71 / 100
2057 ms17920 KiB
#include "shortcut.h" #include <bits/stdc++.h> using namespace std; #define pb push_back #define ar array #define all(x) x.begin(), x.end() using i64 = long long; const i64 inf = 1e15; struct square{ i64 x1, x2, y1, y2; square(i64 x1 = 0, i64 x2 = 0, i64 y1 = 0, i64 y2 = 0) : x1(x1), x2(x2), y1(y1), y2(y2) {} square f(square q){ return square(max(x1, q.x1), min(x2, q.x2), max(y1, q.y1), min(y2, q.y2)); } bool check(i64 x, i64 y){ return x1 <= x && x2 >= x && y1 <= y && y2 >= y; } }; struct SegTree{ vector <ar<i64,2>> T; int n; bool isMax; SegTree(int n, bool isMax = false) : n(n), isMax(isMax) { T.resize(n * 4 + 5, {inf, -1}); } void upd(int v, int l, int r, int p, i64 x, int j){ if ( l == r ){ if ( T[v][0] > x ){ T[v] = {x, j}; } return; } int m = (l + r) / 2; if ( p <= m ) upd(v * 2, l, m, p, x, j); else upd(v * 2 + 1, m + 1, r, p, x, j); T[v] = min(T[v * 2], T[v * 2 + 1]); } void upd(int p, i64 x, int j){ if ( isMax ) x = -x; upd(1, 0, n, p, x, j); } ar <i64,2> get(int v, int l, int r, int tl, int tr){ ar <i64,2> ret = {inf, -1}; if ( l > tr or r < tl ) return ret; if ( tl <= l && tr >= r ){ return T[v]; } int m = (l + r) / 2; return min(get(v * 2, l, m, tl, tr), get(v * 2 + 1, m + 1, r, tl, tr)); } int get(int l, int r){ return get(1, 0, n, l, r)[1]; } }; long long find_shortcut(int n, std::vector<int> L, std::vector<int> d, int C){ vector <i64> x(n), A(n), B(n); for ( int i = 1; i < n; i++ ){ x[i] = x[i - 1] + L[i - 1]; } for ( int i = 0; i < n; i++ ){ A[i] = x[i] + d[i]; B[i] = x[i] - d[i]; } auto P = B; P.pb(-inf), P.pb(inf); sort(all(P)); P.resize(unique(all(P)) - P.begin()); int m = P.size(); auto get = [&](i64 x){ return lower_bound(all(P), x) - P.begin(); }; auto ok = [&](i64 k){ i64 kk = k - C; vector <ar<i64,3>> pt; auto add = [&](int i, int j){ if ( i == -1 ) return; pt.pb({x[i] + x[j], x[i] - x[j], kk - (d[i] + d[j])}); }; vector <SegTree> seg(4, SegTree(m)); seg[1] = seg[3] = SegTree(m, 1); for ( int i = 0; i < n; i++ ){ int u = get(A[i] - k) - 1, v = get(B[i]); vector <i64> q = {A[i], A[i], B[i], B[i]}; for ( int j = 0; j < 4; j++ ){ add(seg[j].get(0, u), i); seg[j].upd(v, q[j], i); } //~ for ( int j = i + 1; j < n; j++ ){ //~ if ( abs(x[i] - x[j]) + d[i] + d[j] <= k ){ //~ continue; //~ } //~ pt.pb({x[i] + x[j], x[i] - x[j], kk - (d[i] + d[j])}); //~ } } if ( pt.empty() ) return true; auto [X, Y, d] = pt[0]; square t = square(X - d, X + d, Y - d, Y + d); for ( int i = 1; i < (int)pt.size(); i++ ){ auto [x, y, d] = pt[i]; t = t.f(square(x - d, x + d, y - d, y + d)); } bool flag = false; for ( int i = 0; i < n; i++ ){ for ( int j = i + 1; j < n; j++ ){ flag |= t.check(x[i] + x[j], x[i] - x[j]); } } return flag; }; i64 l = 0, r = 1e15; while ( l < r ){ i64 m = (l + r) / 2; if ( ok(m) ){ r = m; } else l = m + 1; } return l; }
#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...