#include "nile.h"
#include <vector>
#include <queue>
#include <algorithm>
#include <array>
#include <iostream>
#include <cassert>
using namespace std;
using II = pair<int,int>;
using III = tuple<int,int,int>;
const int INF = 1e9 + 123;
struct DisjointSet {
vector<int> par;
vector<int> sz;
vector< array<int,3> > min_cost;
long long total_cost;
DisjointSet(vector<int> _cost) : par(_cost.size(), -1), sz(_cost.size(), 1) {
total_cost = 0;
for (int c : _cost) {
min_cost.push_back({c, INF, INF});
total_cost += c;
}
}
int find(int x, bool trace = false) {
if (par[x] < 0) return x;
return par[x] = find(par[x]);
}
void update_extra_cost(int x, int c) {
x = find(x);
if (sz[x] % 2 == 1) {
total_cost -= min( min_cost[x][0], min_cost[x][2] );
}
min_cost[x][2] = min(min_cost[x][2], c);
if (sz[x] % 2 == 1) {
total_cost += min( min_cost[x][0], min_cost[x][2] );
}
}
void join(int x, int y) {
x = find(x);
y = find(y);
assert(x != y);
if (sz[y] % 2 == 1) {
// remove cost of y component
total_cost -= min( min_cost[y][0], min_cost[y][2] );
}
if (sz[x] % 2 == 1) {
// remove cost of x component
total_cost -= min( min_cost[x][0], min_cost[x][2] );
}
if (sz[x] % 2 == 0) {
min_cost[x][0] = min(min_cost[x][0], min_cost[y][0]);
min_cost[x][1] = min(min_cost[x][1], min_cost[y][1]);
}
else {
min_cost[x][0] = min(min_cost[x][0], min_cost[y][1]);
min_cost[x][1] = min(min_cost[x][1], min_cost[y][0]);
}
min_cost[x][2] = min(min_cost[x][2], min_cost[y][2]);
par[y] = x;
sz[x] += sz[y];
if (sz[x] % 2 == 1) {
total_cost += min( min_cost[x][0], min_cost[x][2] );
}
}
};
struct Artifact {
int weight;
int cost;
};
vector<long long> calculate_costs(vector<int> W, vector<int> A, vector<int> B,
vector<int> E) {
// Full solution
const int N = W.size();
if (N == 1)
return vector<long long>(N, A[0]);
long long base_cost = 0;
for (int i = 0; i < N; i++)
base_cost += B[i];
cerr << "base_cost: " << base_cost << endl;
const int Q = E.size();
vector<long long> R(Q, base_cost);
vector<Artifact> artifacts;
for (int i = 0; i < N; i++)
artifacts.push_back({W[i], A[i]-B[i]});
sort(artifacts.begin(), artifacts.end(),
[&] (Artifact a, Artifact b) -> bool {return a.weight < b.weight; });
vector<int> C(N);
for (int i = 0; i < N; i++)
C[i] = artifacts[i].cost;
priority_queue< III, vector<III>, greater<III> > events;
for (int i = 0; i < N-1; ++i)
events.emplace( artifacts[i+1].weight - artifacts[i].weight, i, 1 );
for (int i = 0; i < N-2; ++i)
events.emplace( artifacts[i+2].weight - artifacts[i].weight, i, 2 );
priority_queue< II, vector<II>, greater<II> > sorted_queries;
for (int j = 0; j < Q; j++)
sorted_queries.emplace( E[j], j );
DisjointSet dset(C);
while (!sorted_queries.empty()) {
auto [e, j] = sorted_queries.top(); sorted_queries.pop();
while (!events.empty()) {
auto [wdif, i, t] = events.top();
if (wdif > e) break;
// cerr << "wdif: " << wdif << " i: " << i << " t: " << t << endl;
events.pop();
if (t == 1)
dset.join(i, i+1);
else
dset.update_extra_cost(i, artifacts[i+1].cost);
}
R[j] += dset.total_cost;
}
return R;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |