Submission #921805

#TimeUsernameProblemLanguageResultExecution timeMemory
921805danikoynovShortcut (IOI16_shortcut)C++14
0 / 100
1 ms600 KiB
#include "shortcut.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 3010; const ll inf = 1e18; int n; ll cpos[maxn], cs[maxn], pref[maxn], bef[maxn], aft[maxn]; ll l[maxn], d[maxn], c; ll dist[maxn]; struct edge { int to; ll w; edge(int _to = 0, ll _w = 0) { to = _to; w = _w; } bool operator < (const edge &e) const { return w > e.w; } }; int used[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; } }; struct point { ll x, y; point(ll _x = 0, ll _y = 0) { x = _x; y = _y; } }; struct rectangle { point centre; ll diagonal; rectangle(point _centre = point(), ll _diagonal = 0) { centre = _centre; diagonal = _diagonal; } }; ll pos[maxn]; struct event { int type; }; struct container { set < pair < ll, ll > > st; void add(pair < ll, ll > cur) { st.insert(cur); /**cout << "add" << endl; for (pair <ll, ll > ch : st) { cout << ch.first << " " << ch.second << endl; }*/ set < pair < ll, ll > > :: iterator it; it = st.find(cur); if (it != st.begin() && prev(it) -> second <= cur.second) { st.erase(it); return; } while(true) { it = next(st.find(cur)); if (it == st.end()) break; if (cur.second <= it -> second) st.erase(it); else break; } /**cout << "result" << endl; for (pair <ll, ll > ch : st) { cout << ch.first << " " << ch.second << endl; } cout << "-----------" << endl;*/ } ll query(ll x) { /**ll res = inf; for (pair < ll, ll > cur : st) { if (cur.first >= x) res = min(res, cur.second); } return res;*/ set < pair < ll, ll > > :: iterator it = st.lower_bound({x, -inf}); if (it == st.end()) return inf; return it -> second; } void clear_container() { st.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 */ /** step -50 step 1000000000000000000 step 1000000000000000000 step -37 step 1000000000000000000 step -34 step -32 step -31 */ /** step 1000000000000000000 step 90 step -6 step 42 step 56 step 63 step 66 step 68 step 69 */ for (int i = 0; i < 4; i ++) opt[i].clear_container(); for (int i = n; i > 0; i --) { /// key - pref[i - 1] + d[i] > x /// key >= x + pref[i - 1] - d[i] + 1 ct[0] = min(ct[0], x - d[i] - c + pos[i] + opt[0].query(x + pref[i - 1] - d[i] + 1)); ///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[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]; } for (int i = 1; i <= n; i ++) { cpos[i] = cpos[i - 1] + l[i - 1]; cpos[i] = max(cpos[i], d[i]); bef[i] = bef[i - 1]; for (int j = 1; j < i; j ++) { bef[i] = max(bef[i], get_dist(i, j) + d[i] + d[j]); } } for (int i = n; i > 0; i --) { cs[i] = cs[i + 1] + l[i]; cs[i] = max(cs[i], d[i]); aft[i] = aft[i + 1]; for (int j = i + 1; j <= n; j ++) { aft[i] = max(aft[i], get_dist(i, j) + d[i] + d[j]); } } ll lf = 0, rf = inf; while(lf <= rf) { 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...