이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>
using namespace std;
const int MAXN = 100007;
int N, par[MAXN], ch[MAXN][2], dep[MAXN], val[MAXN], ft[MAXN];
bool isRoot(int u) { return u != ch[par[u]][0] && u != ch[par[u]][1]; }
bool dir(int u) { return u == ch[par[u]][1]; }
void rot(int u) {
int p = par[u], g = par[p], k = dir(u);
if (!isRoot(p)) ch[g][dir(p)] = u;
par[u] = g;
par[ch[p][k] = ch[u][!k]] = p;
par[ch[u][!k] = p] = u;
}
void splay(int u) {
for (; !isRoot(u); rot(u)) {
if (!isRoot(par[u])) rot(dir(u) == dir(par[u]) ? par[u] : u);
}
}
int64_t access(int u) {
vector<tuple<int, int, int>> segs;
for (int v = 0; u; v = u, u = par[v]) {
splay(u);
int x = ch[u][1];
ch[u][1] = v;
while (ch[u][0]) u = ch[u][0];
splay(u);
if (x) {
while (ch[x][0]) x = ch[x][0];
splay(x);
val[x] = val[u];
}
if (v) { // ignore first segment ({B_j})
segs.emplace_back(val[u], dep[u] + 1, dep[v] - dep[u]);
}
}
int64_t cost = 0;
sort(segs.begin(), segs.end());
reverse(segs.begin(), segs.end());
for (auto tmp : segs) {
int p, x;
tie(ignore, p, x) = tmp;
for (int i = p; i > 0; i -= i & (-i)) cost += (int64_t) ft[i] * x;
for (int i = p; i <= N; i += i & (-i)) ft[i] += x;
}
for (auto tmp : segs) {
int p, x;
tie(ignore, p, x) = tmp;
for (int i = p; i <= N; i += i & (-i)) ft[i] -= x;
}
return cost;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> N;
for (int u = 1; u <= N; ++u) {
cin >> val[u];
}
for (int i = 0; i < N - 1; ++i) {
int u, v;
cin >> u >> v;
dep[v] = dep[u] + 1, par[v] = u;
cout << access(v) << '\n';
val[1] = val[v];
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |