CSES - Shared codeLink to this code:
https://cses.fi/paste/2d2d33b5dcb178376fad79/
#include<bits/stdc++.h>
#define ll long long int
using namespace std;
ll M = 1e9 + 7;
// author: Krishna Sharma
bool is_ancestor(int a, int b, vector<pair<int, int>>&inout) {
if (a == -1) return true;
return (inout[a].first <= inout[b].first && inout[a].second >= inout[b].second);
}
int lca(int a, int b, vector<pair<int, int>>&inout, vector<vector<int>> &par) {
if (is_ancestor(a, b, inout)) return a;
if (is_ancestor(b, a, inout)) return b;
for (int k = 32; k >= 0; k--) {
int parx = par[a][k];
if (!is_ancestor(parx, b, inout)) {
a = parx;
}
}
return par[a][0];
}
int fn(int n, vector<vector<int>> &v, vector<pair<int, int>>&inout, int c, int par) {
inout[n].first = c;
for (auto i : v[n]) {
if (i == par) continue;
c = fn(i, v, inout, c + 1, n);
}
inout[n].second = c + 1;
return c + 1;
}
void dfs(int n, vector<vector<int>> &v, vector<int>&level, int par, vector<vector<int>> &p) {
p[n][0] = par;
for (auto i : v[n]) {
if (i == par) continue;
level[i] = level[n] + 1;
dfs(i, v, level, n, p);
}
}
void fns(int n, vector<vector<int>> &v, vector<long long> &values, int par) {
for (auto i : v[n]) {
if (i == par) continue;
fns(i, v, values, n);
values[n] = values[n] + values[i];
}
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> v(n + 1);
for (int i = 0; i < n - 1; i++) {
int x, y;
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
vector<pair<int, int>> paths;
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
paths.push_back({x, y});
}
vector<int> level(n + 1, 0);
vector<pair<int, int>>inout(n + 1, {0, 0});
fn(1, v, inout, 0, -1);
vector<vector<int>> par(n + 1, vector<int>(64, -1));
dfs(1, v, level, -1, par);
for (int i = 1; i <= n; i++) {
for (int j = 1; j < 63; j++) {
int take = par[i][j - 1];
int parent = -1;
if (take != -1) parent = par[take][j - 1];
par[i][j] = parent;
}
}
vector<long long> values(n + 1, 0);
for (auto i : paths) {
int a = i.first;
int b = i.second;
if (level[a] > level[b]) swap(a, b);
if (is_ancestor(a, b, inout)) {
int take = par[a][0];
if (take == -1);
else values[take]--;
values[b]++;
}
else {
int ans = lca(a, b, inout, par);
int take = par[ans][0];
if (take == -1);
else values[take]--;
values[ans]--;
values[a]++;
values[b]++;
}
}
fns(1, v, values, -1);
for (int i = 1; i <= n; i++) cout << values[i] << " ";
}