제출 #641013

#제출 시각아이디문제언어결과실행 시간메모리
641013piOOEShortcut (IOI16_shortcut)C++17
38 / 100
2096 ms106900 KiB
#pragma GCC optimize("O3,unroll-loops") #include <bits/stdc++.h> #include "shortcut.h" using namespace std; using ll = long long; constexpr int N = 3001; int cant[N][N], mx_pref[N][N], mx_suf[N][N]; int sz[N], nxt[N][N]; bool wtf[N]; ll pref[N]; inline ll dist(int i, int j) { if (i > j) swap(i, j); return pref[j] - pref[i]; } ll find_shortcut(int n, vector<int> l, vector<int> d, int c) { pref[0] = 0; for (int i = 0; i < n - 1; ++i) { pref[i + 1] = pref[i] + l[i]; } ll high = 0; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { ll val = dist(i, j) + d[i] + d[j]; if (high < val) { high = val; } } } ll low = 0; while (low + 1 < high) { ll mid = (low + high) >> 1; auto check = [&]() -> bool { vector<int> prefix; int mn = n; memset(wtf, 0, sizeof(wtf)); memset(sz, 0, sizeof(sz)); for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (dist(i, j) + d[i] + d[j] > mid) { wtf[j] = true; cant[i][sz[i]++] = j; } } if (sz[i]) { if (wtf[i]) { return false; } if (mn > cant[i][0]) { mn = cant[i][0]; } fill(nxt[i], nxt[i] + n + 1, sz[i]); for (int j = 0; j < sz[i]; ++j) { nxt[i][cant[i][j]] = j; } for (int j = n - 1; j > -1; --j) { if (nxt[i][j] == sz[i]) { nxt[i][j] = nxt[i][j + 1]; } } prefix.push_back(i); for (int j = 0; j < sz[i]; ++j) { if (j == 0 || d[cant[i][j]] > dist(cant[i][j], mx_pref[i][j - 1]) + d[mx_pref[i][j - 1]]) { mx_pref[i][j] = cant[i][j]; } else { mx_pref[i][j] = mx_pref[i][j - 1]; } } for (int j = sz[i] - 1; j > -1; --j) { if (j == sz[i] - 1 || d[cant[i][j]] > dist(cant[i][j], mx_suf[i][j + 1]) + d[mx_suf[i][j + 1]]) { mx_suf[i][j] = cant[i][j]; } else { mx_suf[i][j] = mx_suf[i][j + 1]; } } } } if (prefix.empty()) { return true; } vector<int> pnt(n); for (int p = prefix[0]; p < mn; ++p) { int L = 0; for (int i: prefix) { ll D = dist(p, i) + d[i]; auto check = [&](int m) -> bool { auto it = nxt[i][m]; if (it == sz[i] || D + c + dist(m, mx_suf[i][it]) + d[mx_suf[i][it]] <= mid) { return true; } else { return false; } }; bool gg = false; while (!check(pnt[i])) { gg = true; ++pnt[i]; } if (!gg) { while (pnt[i] > 0 && check(pnt[i] - 1)) { --pnt[i]; } } if (L < pnt[i]) { L = pnt[i]; } } if (L == n) { continue; } bool yay = true; for (int i: prefix) { int m = L; auto it = nxt[i][m + 1]; if (it != 0 && dist(p, i) + d[i] + c + dist(m, mx_pref[i][it - 1]) + d[mx_pref[i][it - 1]] > mid) { yay = false; break; } } if (yay) { return true; } } return false; }; if (check()) { high = mid; } else { low = mid; } } return high; }
#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...