Submission #1231311

#TimeUsernameProblemLanguageResultExecution timeMemory
1231311bangan나일강 (IOI24_nile)C++20
100 / 100
81 ms11960 KiB
#include "nile.h"
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)

#define pb push_back
#define ALL(a) a.begin(), a.end()

const ll INF = 1ll << 30;

std::vector<long long> calculate_costs(std::vector<int> W, std::vector<int> A, std::vector<int> B, std::vector<int> E) {
    int N = W.size();
    int Q = E.size();

    vector<int> ord(N);
    iota(ALL(ord), 0);
    sort(ALL(ord), [&](int i, int j) {
        return W[i]<W[j];
    });

    auto f = [&](pair<int, int> a) {
        auto [i, j] = a;
        return W[ord[j]]-W[ord[i]];
    };

    vector<pair<int, int>> edges;
    for (int i=0; i+1 < N; i++) edges.emplace_back(i, i+1);
    for (int i=0; i+2 < N; i++) edges.emplace_back(i, i+2);
    sort(ALL(edges), [&](auto a, auto b) {
        if (f(a)==f(b)) return a.second-a.first < b.second-b.first;
        else return f(a)<f(b);
    });

    vector<int> qry(Q);
    iota(ALL(qry), 0);
    sort(ALL(qry), [&](int i, int j) {
        return E[i]<E[j];
    });

    ll sum_res = accumulate(ALL(A), 0ll);
    vector<int> par(N), sz(N);
    vector<ll> sum(N);
    vector<array<ll, 2>> diff(N), esp(N);
    vector<ll> res(N);
    for (int i=0; i<N; i++) {
        par[i]=i;
        sz[i]=1;
        sum[i] = B[ord[i]];
        diff[i] = {A[ord[i]]-B[ord[i]], INF};
        esp[i] = {INF, INF};
        res[i] = A[ord[i]];
    }

    auto find = [&](auto self, int v) -> int {
        return par[v]==v ? v : par[v] = self(self, par[v]);
    };
    auto merge = [&](int ii, int jj) -> void {
        int i = find(find, ii);
        int j = find(find, jj);
        
        if (i != j) {
            assert(i<j);
            assert(jj-ii == 1);
            sum_res -= res[i];
            sum_res -= res[j];

            par[j] = i;
            sz[i] += sz[j];
            sum[i] += sum[j];
            
            {
                int t = (i%2 != j%2);
                
                chmin(diff[i][0], diff[j][0^t]);
                chmin(diff[i][1], diff[j][1^t]);

                chmin(esp[i][0], esp[j][0^t]);
                chmin(esp[i][1], esp[j][1^t]);
            }

            res[i] = sum[i] + min(diff[i][0], esp[i][1]);
            if (sz[i]%2 == 0) res[i] = sum[i];
            sum_res += res[i];
        }
        else {
            assert(jj-ii == 2);
            sum_res -= res[i];
            int k = ii+1;
            int t = (i%2 != k%2);
            chmin(esp[i][t], 0ll + A[ord[k]]-B[ord[k]]);
            res[i] = sum[i] + min(diff[i][0], esp[i][1]);
            if (sz[i]%2 == 0) res[i] = sum[i];
            sum_res += res[i];
        }
    };

    auto cur = edges.begin();
    vector<ll> ans(Q);

    for (int id : qry) {
        while (cur != edges.end() && f(*cur) <= E[id]) {
            merge(cur->first, cur->second);
            cur++;
        }
        ans[id] = sum_res;
    }
    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...