Submission #921847

#TimeUsernameProblemLanguageResultExecution timeMemory
921847danikoynovShortcut (IOI16_shortcut)C++14
0 / 100
1 ms2396 KiB
#include "shortcut.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 10; const ll inf = 1e18; int n; ll pref[maxn]; ll l[maxn], d[maxn], c; ll dist[maxn]; ll get_dist(int l, int r) { if (l > r) swap(l, r); return pref[r - 1] - pref[l - 1]; } const int maxlog = 21; struct sparse_table { ll dpos[maxlog][maxn]; int lg[maxn]; void build(vector < ll > values) { int len = values.size(); for (int i = 1; i <= len; i ++) { lg[i] = lg[i / 2] + 1; dpos[0][i] = values[i - 1]; } for (int j = 1; j < lg[len]; j ++) { for (int i = 1; i <= len - (1 << j) + 1; i ++) { dpos[j][i] = dpos[j - 1][i + (1 << (j - 1))]; if (dpos[j - 1][i] > dpos[j][i]) dpos[j][i] = dpos[j - 1][i]; } } } ll query(int l, int r) { if (l > r) return 0; int mlog = lg[r - l + 1] - 1; ll ans = dpos[mlog][r - (1 << mlog) + 1]; if (dpos[mlog][l] > ans) ans = dpos[mlog][l]; return ans; } }; ll pos[maxn]; struct container { map < ll, ll > mp; void add(pair < ll, ll > cur) { cur.second = - cur.second; map < ll, ll > :: iterator it = mp.lower_bound(cur.first); if (it != mp.end() && it -> second >= cur.second) return; it = mp.insert(it, cur);///mp[cur.first] = cur.second; /**cout << "add" << endl; for (pair <ll, ll > ch : st) { cout << ch.first << " " << ch.second << endl; }*/ it -> second = cur.second; ///it = mp.find(cur.first); while(it != mp.begin() && prev(it) -> second <= cur.second) { it = prev(it); it -> second = cur.second; //mp.erase(prev(it)); } /**cout << "result" << endl; for (pair <ll, ll > ch : st) { cout << ch.first << " " << ch.second << endl; } cout << "-----------" << endl;*/ } ll query(ll x) { map < ll, ll > :: iterator it = mp.lower_bound(x); if (it == mp.end()) return inf; return -it -> second; } void clear_container() { mp.clear(); } }; container opt[4]; bool check(ll x) { ll ct[4] = {inf, inf, inf, inf}; /** 0 - up up 1 - up down 2 - down up 3 - down down */ for (int i = 0; i < 4; i ++) opt[i].clear_container(); ll base, nec; for (int i = n; i > 0; i --) { /// key - pref[i - 1] + d[i] > x /// key >= x + pref[i - 1] - d[i] + 1 base = x - d[i] - c; nec = x + pref[i - 1] - d[i] + 1; ct[0] = min(ct[0], base + pos[i] + opt[0].query(nec)); ct[1] = min(ct[1], base + pos[i] + opt[1].query(nec)); ct[2] = min(ct[2], base - pos[i] + opt[0].query(nec)); ct[3] = min(ct[3], base - pos[i] + opt[2].query(nec)); ///ct[0] = min(ct[0], x - d[i] - c + pos[i] + opt[0]); /**for (int j = i + 1; j <= n; j ++) { ll path = pref[j - 1] - pref[i - 1] + d[i] + d[j]; if (path <= x) continue; /// |x[i] - x[l]| + |x[j] - x[r]| + d[i] + d[j] + c<= k /// |x[l] - x[i]| + |x[r] - x[j]| <= k - d[i] - d[j] - c ///ct[0] = min(ct[0], x - d[i] - d[j] - c + pos[i] + pos[j]); ///ct[1] = min(ct[1], x - d[i] - d[j] - c + pos[i] - pos[j]); ///ct[2] = min(ct[2], x - d[i] - d[j] - c - pos[i] + pos[j]); ///ct[3] = min(ct[3], x - d[i] - d[j] - c - pos[i] - pos[j]); }*/ opt[0].add({pref[i - 1] + d[i], - d[i] + pos[i]}); opt[1].add({pref[i - 1] + d[i], - d[i] - pos[i]}); // opt[2].add({pref[i - 1] + d[i], - d[i] + pos[i]}); //opt[3].add({pref[i - 1] + d[i], - d[i] - pos[i]}); ///opt[0] = min(opt[0], - d[i] - pos[i]); } ///cout << "step " << ct[0] << endl; /**for (int i = 1; i <= n; i ++) for (int j = 1; j <= n; j ++) { if (pos[i] + pos[j] <= ct[0] && pos[i] - pos[j] <= ct[1] && - pos[i] + pos[j] <= ct[2] && - pos[i] - pos[j] <= ct[3]) return true; } return false;*/ for (int i = 1; i <= n; i ++) { ll top = inf, bot = -inf; /// pos[i] + pos[j] <= ct[0] ---- pos[j] <= ct[0] - pos[i] top = min(top, ct[0] - pos[i]); /// pos[i] - pos[j] <= ct[1] --- pos[j] >= pos[i] - ct[1] bot = max(bot, pos[i] - ct[1]); /// - pos[i] + pos[j] <= ct[2] --- pos[j] <= ct[2] + pos[i] top = min(top, ct[2] + pos[i]); /// -pos[i] - pos[j] <= ct[3] --- pos[j] >= - ct[3] - pos[i] bot = max(bot, - ct[3] - pos[i]); int lf = 1, rf = n; while(lf <= rf) { int mf = (lf + rf) / 2; if (pos[mf] < bot) lf = mf + 1; else rf = mf - 1; } if (lf > n) continue; if (pos[lf] <= top) return true; } return false; } ll find_shortcut(int N, vector<int> L, vector<int> D, int C) { n = N; c = C; for (int i = 0; i < n - 1; i ++) l[i + 1] = L[i]; for (int i = 0; i < n; i ++) d[i + 1] = D[i]; pos[1] = 0; for (int i = 2; i <= n; i ++) { pos[i] = pos[i - 1] + l[i - 1]; } for (int i = 1; i <= n; i ++) { pref[i] = pref[i - 1] + l[i]; } ll lf = 0, rf = n * pref[n] + 2e9 + 10; while(lf <= rf) { ///cout << lf << " " << rf << endl; ll mf = (lf + rf) / 2; if (check(mf)) rf = mf - 1; else lf = mf + 1; } return lf; }
#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...