(構造/樹形dp)牛客訓練賽32-B:Xor Path
阿新 • • 發佈:2018-12-03
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; }