結果
| 問題 |
No.2654 [Cherry 6th Tune] Re: start! (Black Sheep)
|
| コンテスト | |
| ユーザー |
hitonanode
|
| 提出日時 | 2024-03-10 18:07:22 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 372 ms / 7,000 ms |
| コード長 | 3,190 bytes |
| コンパイル時間 | 1,071 ms |
| コンパイル使用メモリ | 103,656 KB |
| 実行使用メモリ | 50,944 KB |
| 最終ジャッジ日時 | 2024-09-29 21:42:48 |
| 合計ジャッジ時間 | 10,329 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 40 |
ソースコード
#include <iostream>
#include <set>
#include <vector>
using namespace std;
using lint = long long;
struct Manager {
lint lo_sum = 0;
lint hi_sum = 0;
multiset<int> lo;
multiset<int> hi;
lint solve() {
if (size() <= 1) return 0;
const int nlo = lo.size();
const int nhi = hi.size();
lint med = *lo.rbegin();
lint ret = hi_sum - med * nhi + med * nlo - lo_sum;
return ret;
}
void balance() {
while (!lo.empty() and !hi.empty() and *lo.rbegin() > *hi.begin()) {
int max_lo = *lo.rbegin();
int min_hi = *hi.begin();
lo.erase(prev(lo.end()));
hi.erase(hi.begin());
lo.insert(min_hi);
hi.insert(max_lo);
lo_sum += min_hi - max_lo;
hi_sum += max_lo - min_hi;
}
while (lo.size() > hi.size() + 1) {
hi.insert(*lo.rbegin());
hi_sum += *lo.rbegin();
lo_sum -= *lo.rbegin();
lo.erase(prev(lo.end()));
}
while (hi.size() > lo.size()) {
lo.insert(*hi.begin());
lo_sum += *hi.begin();
hi_sum -= *hi.begin();
hi.erase(hi.begin());
}
}
void add(int x) {
if (lo.empty() or x <= *lo.rbegin()) {
lo.insert(x);
lo_sum += x;
} else {
hi.insert(x);
hi_sum += x;
}
balance();
}
void erase(int x) {
if (lo.count(x)) {
lo.erase(lo.find(x));
lo_sum -= x;
} else {
hi.erase(hi.find(x));
hi_sum -= x;
}
balance();
}
int size() const { return lo.size() + hi.size(); }
int min() const { return *lo.begin(); }
int max() const { return *hi.rbegin(); }
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int N;
cin >> N;
vector<int> A(N + 1);
for (auto &a : A) cin >> a;
vector<vector<int>> to(N + 1);
for (int e = 0; e < N; ++e) {
int a, b;
cin >> a >> b;
to.at(a).push_back(b);
to.at(b).push_back(a);
}
Manager manager;
vector<lint> ret(N, -1);
auto rec = [&](auto &&self, int now, int prv) -> void {
manager.add(A.at(now));
if (now) {
if (manager.size() <= 2) {
ret.at(now - 1) = -1;
} else {
int max = manager.max();
int min = manager.min();
if (max == min) {
ret.at(now - 1) = 1;
} else {
manager.erase(max);
lint tmp = manager.solve();
manager.add(max);
manager.erase(min);
tmp = std::min(tmp, manager.solve());
manager.add(min);
ret.at(now - 1) = tmp;
}
}
}
for (int nxt : to.at(now)) {
if (nxt == prv) continue;
self(self, nxt, now);
}
manager.erase(A.at(now));
};
rec(rec, 0, -1);
for (auto r : ret) cout << r << '\n';
}
hitonanode