Submission #1343460

#TimeUsernameProblemLanguageResultExecution timeMemory
1343460retardeShortcut (IOI16_shortcut)C++20
0 / 100
1 ms376 KiB
#include "shortcut.h"
#include <bits/stdc++.h>
using namespace std;
// #define long long long long

long long n, c;
vector<long long> l, d;
vector<long long> dist;

long long t(long long l, long long r) {
    if (l > r) {return 0; swap(l, r);}
    return dist[r] - dist[l];
}

long long diam(long long l, long long r) {
    // build shortcut l -> r
    long long ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0, ans5 = 0;

    vector<vector<long long>> maxR(n, vector<long long>(n)), maxBruh(n, vector<long long>(n));
    for (long long i = 0; i < n; i++) {
        maxR[i][i] = d[i] + dist[i];
        for (long long j = i + 1; j < n; j++) {
            maxR[i][j] = max(maxR[i][j - 1], d[j] + dist[j]);
        }
    }
    for (long long i = 0; i < n; i++) {
        maxBruh[i][i] = d[i] - dist[i];
        for (long long j = i + 1; j < n; j++) {
            maxBruh[i][j] = max(maxBruh[i][j - 1], d[j] - dist[j]);
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = i - 1; j >= 0; j--) {
            maxBruh[i][j] = maxR[i][j] = -1e18;
        }
    }



    // both on left
    long long mxL = 0;
    long long mx = 0;
    for (long long i = 0; i <= l; i++) {
        ans1 = max(ans1, dist[i] + d[i] + mx);
        mx = max(mx, d[i] - dist[i]);
    }
    mxL = mx;


    // both on right
    long long mxR = 0;
    mx = -dist[r];
    for (long long i = r; i < n; i++) {
        ans2 = max(ans2, dist[i] + d[i] + mx);
        // cout << i << " ans2 " << ans2 << '\n';
        mx = max(mx, d[i] - dist[i]);
        mxR = max(mxR, dist[i] + d[i]);
    }

    // I-out-J-in
    for (long long i = l; i <= r; i++) {
        long long cost = min(t(l, i), t(i, r) + c) + d[i];
        // worst guy <= l? mxL
        // cout << i << " " << dist[l] << " + " << mxL << " + " << cost << '\n';
        ans3 = max(ans3, dist[l] + mxL + cost);
    }

    // I-in-J-out
    for (long long i = l; i <= r; i++) {
        long long cost = min(t(i, r), t(i, l) + c) + d[i];
        // worst guy >= r?
        // cout << i << " ans4 " << cost << " + " << mxR << " - " << dist[r] << '\n';
        ans4 = max(ans4, cost + mxR - dist[r]);
    }

    // both in :C
    long long ptr = l;
    for (long long i = l; i < r-1; i++) {
        while (t(i, ptr) < t(l, r) - t(i, ptr) + c) {
            if (ptr > r) break; // maybe = too?
            ptr++;
        }
        // cout << i << " starts wrap at " << ptr << '\n';
        // cout << "notwrap: " << d[i] + maxR[i + 1][ptr - 1] - dist[i] << '\n';
        // if (ptr <= r) cout << d[i] << " + " << maxR[i + 1][ptr - 1] << " - " << dist[i] << '\n';
        // if (ptr <= r) cout << "wrap: " << dist[i] + d[i] + dist[r] - dist[l] + maxBruh[ptr][r] + c << '\n';

        // at ptr i do a wrap around
        if (ptr <= r) ans5 = max(ans5, d[i] + maxR[i + 1][ptr - 1] - dist[i]);
        if (ptr <= r) ans5 = max(ans5, dist[i] + d[i] + dist[r] - dist[l] + maxBruh[ptr][r] + c);
    }


    // wide
    int bridge = min(dist[r] - dist[l], c);
    long long ans6 = bridge + (maxBruh[0][l] + dist[l]) + (maxR[r][n - 1] - dist[r]);
    // cout << "ans6 " << bridge << " + " << (maxBruh[0][l] + dist[l]) << " + " << (maxR[r][n - 1] - dist[r]) << "\n";


    // cout << ans1 << " " << ans2 << " " << ans3 << " " << ans4 << " " << ans5 << " " << ans6 << "\n";
    return max({ans1, ans2, ans3, ans4, ans5, ans6});
}

long long find_shortcut(int n_f, vector<int> l_f, vector<int> d_f, int c_f)
{
    n = n_f; c = c_f; 
    for (auto &x : l_f) l.push_back(x);
    for (auto &x : d_f) d.push_back(x);
    dist.resize(n);

    for (long long i = 1; i < n; i++) {
        dist[i] = dist[i - 1] + l_f[i - 1];
    }

    if (n == 2) {
        assert(dist[1] - dist[0] >= c);
    }

    // int ans = diam(2, 7);

    long long ans = 1e18;
    for (long long i = 0; i < n; i++) {
        for (long long j = i+1; j < n; j++) {
            // build i, j
            long long x = diam(i, j);
            ans = min(ans, x);
            // cout << x << " ";
        }
        // cout << '\n';
    }

    return ans;
}
#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...