# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1162302 | fzyzzz_z | Mergers (JOI19_mergers) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 500005, L = 19;
int anc[N][L];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int n, k;
cin >> n >> k;
vector<vector<int>> g(n);
for (int i = 0; i < n - 1; ++i) {
int x, y;
cin >> x >> y;
x--; y--;
g[x].push_back(y);
g[y].push_back(x);
}
vector<int> path, depth(n, 0), tin(n);
int timer = 0;
function<void(int, int)> dfs0 = [&] (int x, int p) -> void {
path.push_back(x);
for (int k = 0; k < L; ++k) {
if ((1 << k) + 1 > path.size()) {
anc[x][k] = -1;
} else {
anc[x][k] = path.at(path.size() - 1 - (1 << k));
}
}
tin[x] = timer++;
for (auto y: g[x]) {
if (y != p) {
depth[y] = depth[x] + 1;
dfs0(y, x);
}
}
path.pop_back();
};
function<int(int, int)> lca = [&] (int x, int y) {
if (depth[x] > depth[y]) swap(x, y);
for (int k = L - 1; k >= 0; --k) {
if (depth[y] - (1 << k) >= depth[x]) {
y = anc[y][k];
}
}
assert(depth[y] == depth[x]);
for (int k = L - 1; k >= 0; --k) {
if (anc[x][k] != -1 && anc[y][k] != -1 && anc[x][k] != anc[y][k]) {
x = anc[x][k];
y = anc[y][k];
}
}
assert(anc[x][0] == anc[y][0]);
if (anc[x][0] != -1) x = anc[x][0];
return x;
};
vector<int> c(n);
vector<vector<int>> xs(n);
for (int i = 0; i < n; ++i) {
cin >> c[i];
xs[--c[i]].push_back(i);
}
vector<int> p(n);
for (int i = 0; i < n; ++i) {
sort(xs[i].begin(), xs[i].end(), [&](const int & x, const int & y){
return tin[x] < tin[y];
});
for (int j = 0; j < (int) xs[i].size() - 1; ++j) {
int x = xs[i][j], y = xs[i][j + 1];
int z = lca(x, y);
if (z != x && z != y) {
p[x]++;
p[y]++;
p[z] -= 2;
} else {
p[x ^ y ^ z]++;
p[z]--;
}
}
}
ce
return 0;
}