제출 #1255966

#제출 시각아이디문제언어결과실행 시간메모리
1255966farhan11679나일강 (IOI24_nile)C++20
컴파일 에러
0 ms0 KiB
// Compile: g++ -std=gnu++17 -O2 -pipe -static -s -o nile nile.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = (ll)9e18;

struct DSU {
    int n;
    vector<int> p;
    vector<int> sz;
    // info per component root:
    vector<int> minIndex;         // minimum index in component
    vector<ll> minC_par[2];      // min C for global parity 0/1 inside comp (use vectors of size n but index by root)
    vector<ll> minEnabled;       // min C among enabled indices in comp (enabled by (i,i+2) pairs)
    DSU(int n=0): n(n), p(n), sz(n), minIndex(n), minEnabled(n, INF) {
        for(int i=0;i<n;i++){ p[i]=i; sz[i]=1; minIndex[i]=i; minC_par[0].push_back(INF); minC_par[1].push_back(INF); }
        // NOTE: we used push_back above; that made the parity arrays length n. We'll access by index.
    }
    int find(int a){ return p[a]==a ? a : p[a]=find(p[a]); }
    // helper to initialize parity minima per node (call before any unions)
    void init_parity_min(int idx, ll Cval){
        minC_par[0][idx] = minC_par[0][idx]; // already INF
        minC_par[1][idx] = minC_par[1][idx];
        int par = idx & 1;
        minC_par[par][idx] = Cval;
    }
    // merge b into a (rooted)
    void unite_roots(int ra, int rb){
        if(ra==rb) return;
        if(sz[ra] < sz[rb]) swap(ra, rb);
        // rb into ra
        p[rb] = ra;
        sz[ra] += sz[rb];
        // min index
        minIndex[ra] = min(minIndex[ra], minIndex[rb]);
        // parity mins
        minC_par[0][ra] = min(minC_par[0][ra], minC_par[0][rb]);
        minC_par[1][ra] = min(minC_par[1][ra], minC_par[1][rb]);
        // enabled mins
        minEnabled[ra] = min(minEnabled[ra], minEnabled[rb]);
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N;
    if(!(cin>>N)) return 0;
    vector<long long> W(N), A(N), B(N);
    for(int i=0;i<N;i++){
        cin >> W[i] >> A[i] >> B[i];
    }
    int Q; cin >> Q;
    vector<long long> E(Q);
    for(int i=0;i<Q;i++) cin >> E[i];

    // Sort by weight, keep mapping
    vector<int> ord(N);
    iota(ord.begin(), ord.end(), 0);
    sort(ord.begin(), ord.end(), [&](int i, int j){ if(W[i]!=W[j]) return W[i]<W[j]; return i<j; });
    vector<int> pos(N); // pos[original_index] = new index
    vector<long long> sW(N), sA(N), sB(N);
    for(int i=0;i<N;i++){
        pos[ord[i]] = i;
        sW[i] = W[ord[i]];
        sA[i] = A[ord[i]];
        sB[i] = B[ord[i]];
    }
    // C = A - B
    vector<ll> C(N);
    ll sumB = 0;
    for(int i=0;i<N;i++){ C[i] = sA[i] - sB[i]; sumB += sB[i]; }

    // Prepare candidate pairs: (i, i+1) and (i, i+2)
    struct PairItem { ll diff; int i; int j; int type; }; // type: 1 = (i,i+1) union, 2 = (i,i+2) enable middle
    vector<PairItem> pairs;
    for(int i=0;i+1<N;i++){
        pairs.push_back({ sW[i+1] - sW[i], i, i+1, 1 });
    }
    for(int i=0;i+2<N;i++){
        pairs.push_back({ sW[i+2] - sW[i], i, i+2, 2 });
    }
    sort(pairs.begin(), pairs.end(), [](const PairItem &a, const PairItem &b){
        if(a.diff!=b.diff) return a.diff < b.diff;
        return a.type < b.type;
    });

    // Sort queries with indexes
    vector<int> qidx(Q);
    iota(qidx.begin(), qidx.end(), 0);
    sort(qidx.begin(), qidx.end(), [&](int a, int b){ if(E[a]!=E[b]) return E[a] < E[b]; return a < b; });

    // DSU and per-component info
    DSU dsu(N);
    // Note: dsu constructor already created parity arrays via push_back. But we need them as vectors sized N and accessible by index.
    // Reconstruct DSU fields properly:
    // (Because of the push_back hack in constructor creating arrays of size N, but easier to reassign properly.)
    dsu = DSU(N);
    // initialize parity minima & enabled
    for(int i=0;i<N;i++){
        int r = dsu.find(i);
        dsu.minC_par[0][i] = INF;
        dsu.minC_par[1][i] = INF;
        int par = i & 1;
        dsu.minC_par[par][i] = C[i];
        dsu.minIndex[i] = i;
        dsu.minEnabled[i] = INF;
        dsu.sz[i] = 1;
    }

    // helper to get component contribution:
    auto comp_contrib = [&](int root)->ll{
        if(dsu.sz[root] % 2 == 0) return 0;
        int L = dsu.minIndex[root];
        int par = L & 1;
        ll best = min(dsu.minC_par[par][root], dsu.minEnabled[root]);
        return best;
    };

    // but since we store parity minima in arrays indexed by root (and when we merge we write into root entries),
    // initial contribution sum is sum C[i]
    ll extra_sum = 0;
    for(int i=0;i<N;i++) extra_sum += C[i];

    // We'll need arrays to check whether an index has been enabled already
    vector<char> enabled(N, 0);

    // pointer over pairs
    int pptr = 0;
    vector<ll> ans(Q);
    for(int qi = 0; qi < Q; ++qi){
        int qid = qidx[qi];
        ll D = E[qid];
        // process pairs with diff <= D
        while(pptr < (int)pairs.size() && pairs[pptr].diff <= D){
            auto &pr = pairs[pptr];
            if(pr.type == 2){
                // (i,i+2) -> enable middle i+1
                int mid = pr.i + 1;
                if(!enabled[mid]){
                    enabled[mid] = 1;
                    int root = dsu.find(mid);
                    // update extra_sum: remove old contribution, update minEnabled, add new contribution
                    ll before = comp_contrib(root);
                    extra_sum -= before;
                    dsu.minEnabled[root] = min(dsu.minEnabled[root], C[mid]);
                    ll after = comp_contrib(root);
                    extra_sum += after;
                }
            } else {
                // (i,i+1) union components
                int u = pr.i, v = pr.j;
                int ru = dsu.find(u), rv = dsu.find(v);
                if(ru != rv){
                    // remove their contributions
                    ll before_u = comp_contrib(ru);
                    ll before_v = comp_contrib(rv);
                    extra_sum -= (before_u + before_v);
                    // merge -- keep root ru as the final root (DSU ensures by size)
                    dsu.unite_roots(ru, rv);
                    int newr = dsu.find(ru); // root after union (should be ru or swapped)
                    // If root changed due to size swap inside unite_roots, ensure parity minima etc are at newr already handled
                    // after unite_roots we have parity mins at new root index
                    // add new contribution
                    ll after = comp_contrib(newr);
                    extra_sum += after;
                }
            }
            pptr++;
        }
        ans[qid] = sumB + extra_sum;
    }

    // output answers in original order
    for(int i=0;i<Q;i++) cout << ans[i] << '\n';
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

/usr/bin/ld: /tmp/cc07ankR.o: in function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/cc1vnJXA.o:nile.cpp:(.text.startup+0x0): first defined here
/usr/bin/ld: /tmp/cc07ankR.o: in function `main':
grader.cpp:(.text.startup+0x30e): undefined reference to `calculate_costs(std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status