Submission #1235415

#TimeUsernameProblemLanguageResultExecution timeMemory
1235415hugo_pmNile (IOI24_nile)C++20
100 / 100
93 ms27412 KiB
#include "nile.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long
using i32 = signed;
constexpr int INF = 2e18;
struct Query {
    int dis, id_qry;
    auto operator<=>(const Query&) const = default;
};
struct Artifact {
    int weight, value;
    auto operator<=>(const Artifact&) const = default;
};

struct Interval {
    int sum_values = 0, cnt_arts = 0;
    int min_even = INF, min_odd = INF, min_skipped = INF;
    int compute() {
        if (cnt_arts % 2 == 0)
            return sum_values;
        else
            return sum_values - min(min_even, min_skipped);
    }
    static Interval singleton(int value) {
        return {value, 1, value, INF, INF};
    }
};

Interval combine(Interval I, Interval J) {
    if (I.cnt_arts % 2)
        swap(J.min_even, J.min_odd);
    return {
        I.sum_values + J.sum_values,
        I.cnt_arts + J.cnt_arts,
        min(I.min_even, J.min_even),
        min(I.min_odd, J.min_odd),
        min(I.min_skipped, J.min_skipped)
    };
}

struct UF { // path compression only
    vector<int> repr;
    vector<Interval> info;
    int cur_answer = 0;
    UF(const vector<Artifact> &arts) {
        repr.resize(arts.size());
        iota(repr.begin(), repr.end(), 0);
        for (auto &art : arts)
            info.push_back(Interval::singleton(art.value));
    }
    int find(int x) {
        if (x != repr[x]) repr[x] = find(repr[x]);
        return repr[x];
    }
    void merge(int x, int y) {
        x = find(x); y = find(y);
        if (x == y) return;
        assert(x < y);
        cur_answer -= info[x].compute() + info[y].compute();
        info[x] = combine(info[x], info[y]);
        cur_answer += info[x].compute();
        repr[y] = x;
    }
};

enum EventType { MERGE_ONE, MERGE_TWO, QUERY };
struct Event {
    int dis; EventType mode; int mode_arg; // {i, i+1}, {i, i+2} or id_qry
    auto operator<=>(const Event&) const = default;
};

vector<int> solve(vector<Artifact> arts, vector<Query> queries) {
    vector<int> answer(queries.size(), 0);
    sort(arts.begin(), arts.end());
    int nb_arts = arts.size();
    vector<Event> events;
    for (int i = 0; i < nb_arts-1; ++i) {
        auto &cur = arts[i], &nxt1 = arts[i+1];
        events.push_back({nxt1.weight - cur.weight, MERGE_ONE, i});
        if (i < nb_arts-2) {
            auto &nxt2 = arts[i+2];
            events.push_back({nxt2.weight - cur.weight, MERGE_TWO, i});
        }
    }
    for (auto &[dis, id_qry] : queries)
        events.push_back({dis, QUERY, id_qry});
    sort(events.begin(), events.end());

    UF uf(arts);
    for (auto &[dis, ev_typ, ev_arg] : events) {
        if (ev_typ == MERGE_ONE) {
            uf.merge(ev_arg, ev_arg+1);
        } else if (ev_typ == MERGE_TWO) {
            int jumped_over = ev_arg+1; // arg->arg+2
            auto &itv = uf.info[uf.find(jumped_over)];
            uf.cur_answer -= itv.compute();
            itv.min_skipped = min(itv.min_skipped, arts[jumped_over].value);
            uf.cur_answer += itv.compute();
        } else {
            assert(ev_typ == QUERY);
            answer[ev_arg] = uf.cur_answer;
        }
    }
    return answer;
}

vector<int> calculate_costs(vector<i32> W, vector<i32> A, vector<i32> B, vector<i32> E) {
    int nb_artifacts = W.size(), nb_queries = E.size();
    vector<Artifact> artifacts;
    for (int i = 0; i < nb_artifacts; ++i) {
        artifacts.push_back({W[i], A[i] - B[i]});
    }
    vector<Query> queries;
    for (int i = 0; i < nb_queries; ++i) {
        queries.push_back({E[i], i});
    }
    vector<int> answer = solve(artifacts, queries);
    int sum_A = accumulate(A.begin(), A.end(), 0ll);
    for (int &x : answer) {
        x = sum_A - x;
    }
    return answer;
}
#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...