classSolution: defminOperationsQueries(self, n: int, edges: List[List[int]], queries: List[List[int]]) -> List[int]: g = [[] for _ inrange(n)] for x, y, w in edges: g[x].append((y, w - 1)) g[y].append((x, w - 1))
m = n.bit_length() pa = [[-1] * m for _ inrange(n)] cnt = [[[0] * 26for _ inrange(m)] for _ inrange(n)] depth = [0] * n defdfs(x: int, fa: int) -> None: pa[x][0] = fa for y, w in g[x]: if y != fa: cnt[y][0][w] = 1 depth[y] = depth[x] + 1 dfs(y, x) dfs(0, -1)
# 倍增模板 for i inrange(m - 1): for x inrange(n): p = pa[x][i] if p != -1: pp = pa[p][i] pa[x][i + 1] = pp for j, (c1, c2) inenumerate(zip(cnt[x][i], cnt[p][i])): cnt[x][i + 1][j] = c1 + c2
ans = [] for x, y in queries: path_len = depth[x] + depth[y] # 最后减去 depth[lca] * 2 cw = [0] * 26 if depth[x] > depth[y]: x, y = y, x
# 使 y 和 x 在同一深度 k = depth[y] - depth[x] for i inrange(k.bit_length()): if (k >> i) & 1: # k 二进制从低到高第 i 位是 1 p = pa[y][i] for j, c inenumerate(cnt[y][i]): cw[j] += c y = p
if y != x: for i inrange(m - 1, -1, -1): px, py = pa[x][i], pa[y][i] if px != py: for j, (c1, c2) inenumerate(zip(cnt[x][i], cnt[y][i])): cw[j] += c1 + c2 x, y = px, py # 同时上跳 2^i 步 for j, (c1, c2) inenumerate(zip(cnt[x][0], cnt[y][0])): cw[j] += c1 + c2 x = pa[x][0]
lca = x path_len -= depth[lca] * 2 ans.append(path_len - max(cw)) return ans
classSolution { publicint[] minOperationsQueries(int n, int[][] edges, int[][] queries) { List<int[]>[] g = newArrayList[n]; Arrays.setAll(g, e -> newArrayList<>()); for (var e : edges) { intx= e[0], y = e[1], w = e[2] - 1; g[x].add(newint[]{y, w}); g[y].add(newint[]{x, w}); }
intm=32 - Integer.numberOfLeadingZeros(n); // n 的二进制长度 varpa=newint[n][m]; for (inti=0; i < n; i++) { Arrays.fill(pa[i], -1); } varcnt=newint[n][m][26]; vardepth=newint[n]; dfs(0, -1, g, pa, cnt, depth);
for (inti=0; i < m - 1; i++) { for (intx=0; x < n; x++) { intp= pa[x][i]; if (p != -1) { intpp= pa[p][i]; pa[x][i + 1] = pp; for (intj=0; j < 26; j++) { cnt[x][i + 1][j] = cnt[x][i][j] + cnt[p][i][j]; } } } }
varans=newint[queries.length]; for (intqi=0; qi < queries.length; qi++) { intx= queries[qi][0], y = queries[qi][1]; intpathLen= depth[x] + depth[y]; varcw=newint[26]; if (depth[x] > depth[y]) { inttemp= x; x = y; y = temp; }
// 让 y 和 x 在同一深度 for (intk= depth[y] - depth[x]; k > 0; k &= k - 1) { inti= Integer.numberOfTrailingZeros(k); intp= pa[y][i]; for (intj=0; j < 26; ++j) { cw[j] += cnt[y][i][j]; } y = p; }
if (y != x) { for (inti= m - 1; i >= 0; i--) { intpx= pa[x][i]; intpy= pa[y][i]; if (px != py) { for (intj=0; j < 26; j++) { cw[j] += cnt[x][i][j] + cnt[y][i][j]; } x = px; y = py; // x 和 y 同时上跳 2^i 步 } } for (intj=0; j < 26; j++) { cw[j] += cnt[x][0][j] + cnt[y][0][j]; } x = pa[x][0]; }
classSolution { public: vector<int> minOperationsQueries(int n, vector<vector<int>> &edges, vector<vector<int>> &queries){ vector<vector<pair<int, int>>> g(n); for (auto &e: edges) { int x = e[0], y = e[1], w = e[2] - 1; g[x].emplace_back(y, w); g[y].emplace_back(x, w); }
int m = 32 - __builtin_clz(n); // n 的二进制长度 vector<vector<int>> pa(n, vector<int>(m, -1)); vector<vector<array<int, 26>>> cnt(n, vector<array<int, 26>>(m)); vector<int> depth(n); function<void(int, int)> dfs = [&](int x, int fa) { pa[x][0] = fa; for (auto [y, w]: g[x]) { if (y != fa) { cnt[y][0][w] = 1; depth[y] = depth[x] + 1; dfs(y, x); } } }; dfs(0, -1);
for (int i = 0; i < m - 1; i++) { for (int x = 0; x < n; x++) { int p = pa[x][i]; if (p != -1) { int pp = pa[p][i]; pa[x][i + 1] = pp; for (int j = 0; j < 26; ++j) { cnt[x][i + 1][j] = cnt[x][i][j] + cnt[p][i][j]; } } } }
vector<int> ans; for (auto &q: queries) { int x = q[0], y = q[1]; int path_len = depth[x] + depth[y]; // 最后减去 depth[lca] * 2 int cw[26]{}; if (depth[x] > depth[y]) { swap(x, y); }
// 让 y 和 x 在同一深度 for (int k = depth[y] - depth[x]; k; k &= k - 1) { int i = __builtin_ctz(k); int p = pa[y][i]; for (int j = 0; j < 26; ++j) { cw[j] += cnt[y][i][j]; } y = p; }
if (y != x) { for (int i = m - 1; i >= 0; i--) { int px = pa[x][i], py = pa[y][i]; if (px != py) { for (int j = 0; j < 26; j++) { cw[j] += cnt[x][i][j] + cnt[y][i][j]; } x = px; y = py; // x 和 y 同时上跳 2^i 步 } } for (int j = 0; j < 26; j++) { cw[j] += cnt[x][0][j] + cnt[y][0][j]; } x = pa[x][0]; }