https://ac.nowcoder.com/acm/contest/272/B
计算树上每个点到其他点得最短路经过的点的异或值的异或值。
第一行一个整数n。
接下来n-1行,每行2个整数u,v,表示u,v之间有一条边。
第n+1行有n个整数,表示每个点的权值ai。
输出所有path(i, j)的异或值
刚开始看到题意求最短路的异或值,以为是lca求树上路径,然后发现后面要是对每个点去求其他点的路径再异或,光这个就n^2了。
正解是对每个点去求被多少条边经过,因为异或的关系,偶数次经过就不算该点了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
vector<int> E[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, u, v;
cin >> n;
vector<int> val(n + 1), sz(n + 1), num(n + 1);
for(int i = 1; i < n; i++) {
cin >> u >> v;
E[u].emplace_back(v);
E[v].emplace_back(u);
}
for(int i = 1; i <= n; i++) cin >> val[i];
function<void(int, int)> dfs = [&](int u, int pre) {
//cout << "u = " << u << " ,pre = " << pre << '\n';
sz[u] = 1;
for(int v : E[u]) {
if(v != pre) {
dfs(v, u);
num[u] = num[u] + sz[u] * sz[v] & 1;
sz[u] += sz[v];
}
}
num[u] = num[u] + (sz[u]) * (n - sz[u]) & 1;
};
dfs(1, 0);
int ans = 0;
for(int i = 1; i <= n; i++)
if(num[i] & 1) ans ^= val[i];
cout << ans << endl;
}