Submission #274586

#TimeUsernameProblemLanguageResultExecution timeMemory
274586hamerinShortcut (IOI16_shortcut)C++17
97 / 100
2100 ms78932 KiB
#include "shortcut.h" #include <bits/stdc++.h> #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") using namespace std; using i64 = long long; using d64 = long double; using pi = pair<int, int>; using pli = pair<i64, i64>; using ti = tuple<int, int, int>; using tli = tuple<i64, i64, i64>; #define iterall(cont) cont.begin(), cont.end() #define prec(n) setprecision(n) << fixed const i64 PINF = numeric_limits<i64>::max(); const i64 NINF = numeric_limits<i64>::min(); class segTree { public: vector<i64> vl; int N; segTree() = default; segTree(int _N) { vl.resize(1 << 18, PINF); N = _N; } void update(int s, int e, int n, int t, i64 ne) { if (s == e) { vl[n] = ne; return; } int m = (s + e) >> 1; int k = n << 1; if (t <= m) update(s, m, k, t, ne); else update(m + 1, e, k + 1, t, ne); vl[n] = min(vl[k], vl[k + 1]); } void update(int t, i64 ne) { update(1, N, 1, t, ne); } i64 query(int s, int e, int n, int l, int r) { if (r < s || e < l) return PINF; if (l <= s && e <= r) return vl[n]; int m = (s + e) >> 1; int k = n << 1; return min(query(s, m, k, l, r), query(m + 1, e, k + 1, l, r)); } i64 query(int l, int r) { return query(1, N, 1, l, r); } }; namespace Helper { bool inRange(int x, int s, int e) { return s <= x && x <= e; } template <typename T> int findIndex(const vector<T> &vec, T &&toFind) { return upper_bound(iterall(vec), toFind) - vec.begin(); } template <typename T> int findIndex(const vector<T> &vec, const T &toFind) { return upper_bound(iterall(vec), toFind) - vec.begin(); } template <typename T> void setmin(T &target, T &&x) { target = min(target, x); } template <typename T> void setmin(T &target, const T &x) { target = min(target, x); } template <typename T> void setmax(T &target, T &&x) { target = max(target, x); } template <typename T> void setmax(T &target, const T &x) { target = max(target, x); } } // namespace Helper i64 find_shortcut(const int N, vector<int> l, vector<int> d, int c) { // preprocessing vector<i64> X(N); for (int i = 1; i < N; i++) X[i] = X[i - 1] + l[i - 1]; vector<i64> x = X; vector<i64> D; copy(iterall(d), back_inserter(D)); vector<pli> XpD(N); for (int i = 0; i < N; i++) XpD[i] = {X[i] + D[i], i}; sort(iterall(XpD)); vector<int> mpp(N); for (int i = 0; i < N; i++) mpp[XpD[i].second] = i; vector<pli> XmD(N); for (int i = 0; i < N; i++) XmD[i] = {X[i] - D[i], i}; sort(iterall(XmD)); vector<int> mpm(N); for (int i = 0; i < N; i++) mpm[XmD[i].second] = i; i64 S = c; i64 s = 0, e = 1e15 + 1e14; while (s < e) { vector<i64> bounds = {NINF, PINF, NINF, PINF}; i64 m = (s + e) >> 1; i64 mms = m - S; i64 curMax, curMin; int ptr = 0; int ptrm = 0; vector<bool> vst(N); for (int i = 0; i < N; i++) { while (ptr < N && XpD[ptr].first <= m + XmD[i].first) vst[mpm[XpD[ptr].second]] = true, ++ptr; while (ptrm < N && vst[ptrm]) ++ptrm; if (ptr == N || ptrm == N) break; i64 xmd = X[XmD[i].second] - D[XmD[i].second]; i64 xpd = X[XmD[i].second] + D[XmD[i].second]; int sptr = ptr; if (XpD[sptr].second == XmD[i].second) sptr++; if (XmD[i].second != XpD[N - 1].second) curMax = XpD[N - 1].first; else if (sptr != N - 1) curMax = XpD[N - 2].first; else continue; if (ptrm != i) curMin = XmD[ptrm].first; else { int tmp = ptrm + 1; while (tmp < N && vst[tmp]) ++tmp; if (tmp == N) continue; curMin = XmD[tmp].first; } Helper::setmax(bounds[0], -mms - xmd + curMax); Helper::setmin(bounds[1], mms - xpd + curMin); Helper::setmax(bounds[2], -mms + xpd + curMax); Helper::setmin(bounds[3], mms + xmd + curMin); if (bounds[0] > bounds[1] || bounds[2] > bounds[3]) break; } bool condition = false; for (int i = 0; i < N; i++) { i64 L = x[i]; i64 lowBound = max(bounds[0] + L, bounds[2] - L); i64 uppBound = min(bounds[1] + L, bounds[3] - L); if (lowBound > uppBound) continue; auto itl = lower_bound(iterall(x), lowBound); auto itr = upper_bound(iterall(x), uppBound); if (itr == x.begin()) continue; if (itl == x.end()) continue; if (itl != itr) { // cout << i << " " << itl - x.begin() << endl; condition = true; break; } } if (condition) e = m; else s = m + 1; } return s; }
#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...