Submission #699351

#TimeUsernameProblemLanguageResultExecution timeMemory
699351CatalinTPalembang Bridges (APIO15_bridge)C++17
49 / 100
2049 ms27320 KiB
#include <vector>
#include <iostream>
#include <cassert>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <unordered_map>
#include <functional>
#include <bitset>
#include <sstream>

using namespace std;

using int64 = long long;

int N, M, K;
vector<pair<int64, int64>> segments;

vector<int64> X;
vector<int64> vec;

map<int64, int> idx;

int64 dist(int64 x, pair<int64, int64> & s) {
    if (s.second < x) {
        return 2 * (x - s.second); 
    } else if (s.second >= x && s.first <= x) {
        return 0;
    } else {
        return 2 * (s.first - x);
    }
}

int64 solve1brute() {
    int64 res = (1LL<<60);
    for (auto & x : vec) {
        int64 cur = 0;
        for (auto & s : segments) {
            cur += dist(x, s);
        }
        res = min(res, cur);
    }
    return res;
}

// optimum right bridge for left bridges in [l, r] is
// in [optl, optr]

vector<int64> dp;

void rec(int l, int r, int optl, int optr) {
    if (l > r)
        return;
    
    int m = (l + r) >> 1;

    int opt = -1;
    int64 bst = (1LL<<60);

    for (int i = max(m + 1, optl); i <= optr; i++) {
        // Compute cost(m, opt)

        int64 cur = 0;
        for (auto & s: segments) {
            cur += min(dist(vec[m], s), dist(vec[i], s));
        }

        if (cur < bst) {
            bst = cur;
            opt = i;
        }
    }

    assert(opt != -1);

    dp[m] = bst;

    rec(l, m - 1, optl, opt);
    rec(m + 1, r, opt, optr);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int64 res = 0;

    cin >> K >> N;

    set<int64> uniq;

    for (int i = 0; i < N; i++) {
        char z1, z2;
        int x1, x2;

        cin >> z1 >> x1 >> z2 >> x2;

        res += abs(x1 - x2);

        if (z1 != z2) {
            segments.emplace_back(min(x1, x2), max(x1, x2));
            uniq.insert(x1);
            uniq.insert(x2);
        }
    }

    uniq.insert(-(1<<30));
    uniq.insert((1LL<<31));

    if (!size(segments)) {
        cout << res << "\n";
        return 0;
    }

    vec = vector<int64>(begin(uniq), end(uniq));
    N = size(vec);

    for (int i = 0; i < N; i++) {
        idx[vec[i]] = i;
    }

    M = size(segments);
    res += M; // every crossed a bridge

    // need at least one bridge;

    dp.assign(N + 2, (1LL<<60));

    rec(0, N - 2, 1, N - 1);

    if (K == 1) {
        cout << res + dp[0] << "\n";
    } else {
        cout << res + (*min_element(begin(dp) + 1, begin(dp) + N - 2)) << "\n";
    }

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