Submission #641027

# Submission time Handle Problem Language Result Execution time Memory
641027 2022-09-15T17:46:30 Z piOOE Shortcut (IOI16_shortcut) C++17
0 / 100
0 ms 340 KB
#pragma GCC optimize("O3")

#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);
                    mx_pref[i][0] = cant[i][0];
                    for (int j = 1; j < sz[i]; ++j) {
                        if (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];
                        }
                    }
                    mx_suf[i][sz[i] - 1] = cant[i][sz[i] - 1];
                    for (int j = sz[i] - 2; j > -1; --j) {
                        if (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];
                        }
                    }
                }
            }
            vector<int> pnt(n);
            mn = min(mn, prefix.back());
            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 time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 340 KB n = 4, incorrect answer: jury 80 vs contestant 110
2 Halted 0 ms 0 KB -