This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
#include "shortcut.h"
const int N = 3e3 + 10;
long long f[N][N], g[N][N];
long long pref[N], suff[N], pref_mx[N], suff_mx[N], pref_l[N];
int pre[N];
long long find_shortcut(int n, std::vector<int> L, std::vector<int> d, int c)
{
assert(f[0][1] == 0);
pref[0] = d[0];
suff[n - 1] = d[n - 1];
for(int i = 1; i < n; i++) {
pref[i] = max(pref[i - 1] + L[i - 1], (long long) d[i]);
pref_mx[i] = max(pref_mx[i - 1], pref[i - 1] + L[i - 1] + d[i]);
}
for(int i = n - 2; i >= 0; i--) {
suff[i] = max(suff[i + 1] + L[i], (long long) d[i]);
suff_mx[i] = max(suff_mx[i + 1], suff[i + 1] + L[i] + d[i]);
}
for(int i = 1; i < n; i++) {
pref_l[i] = pref_l[i - 1] + L[i - 1];
}
for(int x = 0; x < n; x++) {
priority_queue<pair<long long, long long> > q;
long long mx = 0;
for(int y = x; y < n; y++) {
q.push({d[y] - pref_l[y], d[y] + pref_l[y] - pref_l[x] + c});
while (!q.empty()) {
long long a, b; tie(a, b) = q.top();
if (a + pref_l[y] >= b) {
mx = max(mx, b);
q.pop();
}
else {
mx = max(mx, a + pref_l[y]);
break;
}
}
f[x][y] = mx;
}
}
for(int x = n - 1; x >= 0; x--) {
priority_queue<pair<long long, long long> > q;
long long mx = 0;
for(int y = x; y >= 0; y--) {
q.push({d[y] + pref_l[y], d[y] + pref_l[x] - pref_l[y] + c});
while (!q.empty()) {
long long a, b; tie(a, b) = q.top();
if (a - pref_l[y] >= b) {
mx = max(mx, b);
q.pop();
}
else {
mx = max(mx, a - pref_l[y]);
break;
}
}
f[x][y] = mx;
}
}
// cout << f[3][1] << endl;
long long l = 0, r = 1e18, ans = -1;
auto check = [&] (long long mid) {
for(int i = n - 1; i >= 0; i--) for(int j = i; j < n; j++) {
g[i][j] = max(g[i + 1][j], g[i][j - 1]);
if (i == j) g[i][j] = -1e18;
else if (pref_l[j] - pref_l[i] + d[i] + d[j] >= mid) {
// cout << i << " " << j << endl;
g[i][j] = max(g[i][j], d[i] + d[j] - pref_l[j] + pref_l[i]);
}
}
// cout << f[1][2] << endl;
// for(int i = 0; i < n; i++) cout << pre[i] << " "; cout << endl;
long long best = 1e18;
for(int x = 0; x < n; x++) {
for(int y = x + 1; y < n; y++) {
long long cost = max(pref_mx[x], suff_mx[y]);
cost = max(cost, pref[x] + suff[y] + min((long long) c, pref_l[y] - pref_l[x]));
if (y + 1 < n) cost = max(cost, f[x][y] + suff[y + 1] + L[y]);
if (x - 1 >= 0) cost = max(cost, f[y][x] + pref[x - 1] + L[x - 1]);
cost = max(cost, g[x][y] + c + pref_l[y] - pref_l[x]);
best = min(best, cost);
// cout << x << " " << y << " " << cost << " " << endl;
}
}
return (best >= mid);
};
// cout << check(18);
// exit(0);
while (l <= r) {
long long mid = l + r >> 1;
if (check(mid)) {
ans = mid;
l = mid + 1;
} else r = mid - 1;
}
return ans;
}
#ifdef ngu
int main()
{
freopen ("task.inp", "r", stdin);
freopen ("task.out", "w", stdout);
int n, c;
assert(2 == scanf("%d%d", &n, &c));
std::vector<int> l(n - 1);
std::vector<int> d(n);
for (int i = 0; i < n - 1; i++)
assert(1 == scanf("%d", &l[i]));
for (int i = 0; i < n; i++)
assert(1 == scanf("%d", &d[i]));
long long t = find_shortcut(n, l, d, c);
printf("%lld\n", t);
return 0;
}
#endif // ngu
Compilation message (stderr)
shortcut.cpp: In function 'long long int find_shortcut(int, std::vector<int>, std::vector<int>, int)':
shortcut.cpp:105:23: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
105 | long long mid = l + r >> 1;
| ~~^~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |