이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "shortcut.h"
#include <bits/stdc++.h>
using namespace std;
// O(N^2 log N) Solution [[71 pts]]
long long N, C, D[3009][3009], A[3009], B[3009], dp[3009];
long long BB[6009], L[6009], LL[6009], L2[6009], FL[6009], FR[6009], Z1[3009][3009], Z2[3009][3009];
void init() {
N = 0; C = 0;
for (int i = 0; i < 19; i++) {
BB[i] = 0; L[i] = 0; A[i] = 0; B[i] = 0; dp[i] = 0; LL[i] = 0; L2[i] = 0;
for (int j = 0; j < 19; j++) D[i][j] = 0;
}
}
void initialize() {
long long ss = 0, sm = -B[0]; FL[0] = 0;
for (int i = 1; i < N; i++) {
ss += A[i - 1];
FL[i] = max(FL[i - 1], (ss + B[i]) - sm);
sm = min(sm, ss - B[i]);
}
ss = 0; sm = -B[N - 1]; FR[N - 1] = 0;
for (int i = N - 2; i >= 0; i--) {
ss += A[i];
FR[i] = max(FR[i + 1], (ss + B[i]) - sm);
sm = min(sm, ss - B[i]);
}
}
long long solve_in(int cl, int cr) {
if (Z1[cl][cr] >= 1) return Z1[cl][cr] - 1LL;
for (int i = cl; i < cr; i++) { L[i - cl] = A[i]; BB[i - cl] = B[i]; } L[cr - cl] = C; BB[cr - cl] = B[cr];
int M = (cr - cl + 1), ep = 0;
ep = 0; for (int i = 0; i <= M * 2; i++) { LL[i + 1] = LL[i] + L[ep]; ep++; if(ep==M) ep = 0; }
ep = 0; for (int i = 0; i <= M * 2; i++) { L2[i] = LL[i] + BB[ep]; ep++; if(ep==M) ep = 0;}
//printf("LL : "); for (int i = 0; i <= M * 2; i++) printf("% 4lld", LL[i]); printf("\n");
//printf("L2 : "); for (int i = 0; i <= M * 2; i++) printf("% 4lld", L2[i]); printf("\n");
long long maxn = 0; for (int i = cl; i <= cr; i++) maxn = max(maxn, B[i]);
int cx = 0; deque<pair<long long, int>> vec;
for (int i = 0; i < M; i++) {
while (LL[cx] - LL[i] <= (LL[M] >> 1)) {
while (!vec.empty() && vec[vec.size() - 1].first <= L2[cx]) vec.pop_back();
vec.push_back(make_pair(L2[cx], cx));
cx++;
}
if (vec.front().second == i) vec.pop_front();
if (!vec.empty()) {
//printf("i = %d, cx = %d, right = %d, left = %d\n", i, cx, (int)vec.front().first, (int)(LL[i] - BB[i]));
maxn = max(maxn, vec.front().first - (LL[i] - BB[i]));
}
}
long long el = -(1LL << 60);
long long sl = 0; for (int i = cl - 1; i >= 0; i--) { sl += A[i]; el = max(el, sl + B[i]); }
for (int i = cl; i <= cr; i++) {
maxn = max(maxn, el + B[i] + min(D[cl][i], D[cl][cr] + C - D[cl][i]));
}
Z1[cl][cr] = maxn + 1LL;
return maxn;
}
long long solve_out(int cl, int cr) {
if (Z2[cl][cr] >= 1LL) return Z2[cl][cr] - 1LL;
long long el = -(1LL << 60), er = -(1LL << 60);
long long sl = 0; for (int i = cl - 1; i >= 0; i--) { sl += A[i]; el = max(el, sl + B[i]); }
long long sr = 0; for (int i = cr; i < N - 1; i++) { sr += A[i]; er = max(er, sr + B[i + 1]); }
long long maxn = 0;
for (int i = cl; i <= cr; i++) {
maxn = max(maxn, er + B[i] + min(D[cr][i], D[cl][cr] + C - D[cr][i]));
}
maxn = max(maxn, el + er + min(C, D[cl][cr]));
maxn = max(maxn, FL[cl]);
maxn = max(maxn, FR[cr]);
Z2[cl][cr] = maxn + 1LL;
return maxn;
}
long long find_shortcut2(int n, vector<int>l, vector<int>f, int c) {
long long ans = (1LL << 60);
for (int u = 0; u < n; u++) {
for (int v = u + 1; v < n; v++) {
vector<vector<long long>> d(n * 2, vector<long long>(n * 2, (1LL<<60)));
for (int k = 0; k < n * 2; k++) d[k][k] = 0;
for (int k = 0; k < n - 1; k++) { d[k][k + 1] = l[k]; d[k + 1][k] = l[k]; }
for (int k = 0; k < n; k++) { d[k][k + n] = f[k]; d[k + n][k] = f[k]; }
d[u][v] = min(d[u][v], 1LL * c); d[v][u] = min(d[v][u], 1LL * c);
for (int k = 0; k < n * 2; k++) {
for (int i = 0; i < n * 2; i++) {
for (int j = 0; j < n * 2; j++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
long long rem = 0; for (int i = 0; i < n * 2; i++) { for (int j = 0; j < n * 2; j++) rem = max(rem, d[i][j]); }
ans = min(ans, rem);
}
}
return ans;
}
long long find_shortcut(int n, vector<int> l, vector<int> d, int c) {
N = n; C = c;
for (int i = 0; i < N; i++) { if (i < N - 1) A[i] = l[i]; B[i] = d[i]; }
for (int i = 0; i < N; i++) {
long long S = 0;
for (int j = i + 1; j < N; j++) {
S += 1LL * l[j - 1];
D[i][j] = S; D[j][i] = S;
}
}
initialize();
long long ans = (1LL << 60);
for (int i = 0; i < N - 1; i++) {
int pl = i + 1, pr = N, pm, cx = N;
for (int j = 0; j < 13; j++) {
pm = (pl + pr) / 2;
long long V1 = solve_in(i, pm);
long long V2 = solve_out(i, pm);
if (V1 > V2) { cx = min(cx, pm); pr = pm; }
else { pl = pm; }
}
if (cx >= i + 2) ans = min(ans, max(solve_in(i, cx - 1), solve_out(i, cx - 1)));
if (cx < N) ans = min(ans, max(solve_in(i, cx), solve_out(i, cx)));
}
return ans;
}
# | 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... |