Submission #549653

#TimeUsernameProblemLanguageResultExecution timeMemory
549653tabr철로 (IOI14_rail)C++17
100 / 100
89 ms600 KiB
#include <bits/stdc++.h>
using namespace std;
#ifdef tabr
#include "library/debug.cpp"
#else
#define debug(...)
#endif

#ifdef tabr
function<int(int, int)> getDistance;
#else
#include "rail.h"
#endif

void findLocation(int n, int first, int loc[], int stype[]) {
    loc[0] = 0;
    stype[0] = 1;
    vector<int> d0(n);
    for (int i = 1; i < n; i++) {
        d0[i] = getDistance(0, i);
    }
    int pos0 = 0;
    int pos1 = (int) (min_element(d0.begin() + 1, d0.end()) - d0.begin());
    loc[pos1] = d0[pos1];
    stype[pos1] = 2;
    vector<int> d1(n);
    d1[0] = d0[pos1];
    for (int i = 1; i < n; i++) {
        if (i != pos1) {
            d1[i] = getDistance(pos1, i);
        }
    }
    vector<int> left;
    vector<int> right;
    left.emplace_back(pos0);
    right.emplace_back(pos1);
    for (int i = 1; i < n; i++) {
        if (i == pos1) {
            continue;
        } else if (d1[i] + d0[pos1] == d0[i]) {
            left.emplace_back(i);
        } else {
            right.emplace_back(i);
        }
    }
    sort(left.begin(), left.end(), [&](int i, int j) {
        return d0[i] < d0[j];
    });
    sort(right.begin(), right.end(), [&](int i, int j) {
        return d0[i] < d0[j];
    });
    reverse(left.begin(), left.end());
    while (left.back() != pos0) {
        int i = left.back();
        loc[i] = d0[i] - 2 * d1[i];
        stype[i] = 1;
        left.pop_back();
    }
    reverse(left.begin(), left.end());
    debug(left);
    debug(right);
    int j = left[0];
    left.erase(left.begin());
    vector<int> l1;
    l1.emplace_back(j);
    for (int i : left) {
        int c = getDistance(j, i);
        int p = d0[pos1] - d1[j] + c;
        int l = -1;
        for (int k : l1) {
            if (p - loc[k] >= 0 && (l == -1 || p - loc[k] <= p - loc[l])) {
                l = k;
            }
        }
        if (l != -1 && d1[i] != d1[l] + (p - loc[l])) {
            loc[i] = d0[pos1] - d1[i];
            stype[i] = 1;
            j = i;
            l1.emplace_back(j);
        } else {
            loc[i] = p;
            stype[i] = 2;
        }
    }
    j = right[0];
    right.erase(right.begin());
    vector<int> r2;
    r2.emplace_back(j);
    for (int i : right) {
        int c = getDistance(j, i);
        int p = d0[j] - c;
        int l = -1;
        for (int k : r2) {
            if (loc[k] - p >= 0 && (l == -1 || loc[k] - p <= loc[l] - p)) {
                l = k;
            }
        }
        if (l != -1 && d0[i] != d0[l] + (loc[l] - p)) {
            loc[i] = d0[i];
            stype[i] = 2;
            j = i;
            r2.emplace_back(j);
        } else {
            loc[i] = p;
            stype[i] = 1;
        }
    }
    for (int i = 0; i < n; i++) {
        loc[i] += first;
    }
}

#ifdef tabr
mt19937 rng((unsigned int) chrono::steady_clock::now().time_since_epoch().count());

int rand_int(int a, int b) {  // [a, b]
    return uniform_int_distribution<int>(a, b)(rng);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    const int n = 5;
    const int m = 100;
    int loc[n] = {};
    int stype[n] = {};
    vector<int> a(n);
    while (true) {
        for (int i = 0; i < n; i++) {
            a[i] = rand_int(0, m);
        }
        auto b = a;
        sort(b.begin(), b.end());
        b.resize(unique(b.begin(), b.end()) - b.begin());
        if (b.size() == a.size() && max_element(a.begin(), a.end()) != a.begin()) {
            break;
        }
    }
    vector<int> b(n);
    for (int i = 0; i < n; i++) {
        b[i] = rand_int(1, 2);
    }
    b[max_element(a.begin(), a.end()) - a.begin()] = 2;
    b[min_element(a.begin(), a.end()) - a.begin()] = 1;
    b[0] = 1;
    vector<vector<int>> d(n, vector<int>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i == j) {
                d[i][j] = 0;
            } else if (a[i] < a[j]) {
                d[i][j] = a[j] - a[i];
                if (b[i] == 2) {
                    int c = (int) 1e9;
                    for (int k = 0; k < n; k++) {
                        if (b[k] == 1 && a[k] < a[i]) {
                            c = min(c, a[i] - a[k]);
                        }
                    }
                    d[i][j] += c * 2;
                }
                if (b[j] == 1) {
                    int c = (int) 1e9;
                    for (int k = 0; k < n; k++) {
                        if (b[k] == 2 && a[k] > a[j]) {
                            c = min(c, a[k] - a[j]);
                        }
                    }
                    d[i][j] += c * 2;
                }
            } else {
                d[i][j] = a[i] - a[j];
                if (b[j] == 2) {
                    int c = (int) 1e9;
                    for (int k = 0; k < n; k++) {
                        if (b[k] == 1 && a[k] < a[j]) {
                            c = min(c, a[j] - a[k]);
                        }
                    }
                    d[i][j] += c * 2;
                }
                if (b[i] == 1) {
                    int c = (int) 1e9;
                    for (int k = 0; k < n; k++) {
                        if (b[k] == 2 && a[k] > a[i]) {
                            c = min(c, a[k] - a[i]);
                        }
                    }
                    d[i][j] += c * 2;
                }
            }
        }
    }
    int cnt = 0;
    getDistance = [&](int i, int j) {
        cnt++;
        return d[i][j];
    };
    findLocation(n, a[0], loc, stype);
    bool ok = true;
    for (int i = 0; i < n; i++) {
        if (a[i] != loc[i] || b[i] != stype[i]) {
            ok = false;
        }
    }
    debug(ok, cnt, cnt <= 3 * (n - 1));
    for (int i = 0; i < n; i++) {
        debug(i);
        debug(loc[i], stype[i]);
        debug(a[i], b[i]);
    }
    debug(d);
    return 0;
}
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...