Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define boAshraf ios_base::sync_with_stdio(false); cin.tie(NULL);
- #define ll long long
- #define sz(s) (int)(s).size()
- #define all(s) (s).begin(),(s).end()
- using namespace std;
- void File();
- void sol();
- const int N=1e5+5,M=30;
- int val[N],mask[M][2];
- class centroid_decomposition {
- vector<bool> centroidMarked;
- vector<int> size;
- ll ans=0;
- void dfsSize(int node, int par) {
- size[node] = 1;
- for (int ch : adj[node])
- if (ch != par && !centroidMarked[ch]) {
- dfsSize(ch, node);
- size[node] += size[ch];
- }
- }
- int getCenter(int node, int par, int size_of_tree) {
- for (int ch : adj[node]) {
- if (ch == par || centroidMarked[ch]) continue;
- if (size[ch] * 2 > size_of_tree)
- return getCenter(ch, node, size_of_tree);
- }
- return node;
- }
- int getCentroid(int src) {
- dfsSize(src, -1);
- int centroid = getCenter(src, -1, size[src]);
- centroidMarked[centroid] = true;
- return centroid;
- }
- int decomposeTree(int root) {
- memset(mask,0,sizeof mask);
- root = getCentroid(root);
- solve(root);
- for (int ch : adj[root]) {
- if (centroidMarked[ch])
- continue;
- int centroid_of_subtree = decomposeTree(ch);
- }
- return root;
- }
- void calc(int node, int par, int x=0) {
- x^=val[node];
- for (int i = 0; i < M; ++i) {
- ans+=(1ll<<i)*mask[i][((x>>i)&1)^1];
- }
- for (int ch : adj[node]) if (ch != par && !centroidMarked[ch])
- calc(ch, node);
- }
- void add(int node, int par, int x=0) {
- x^=val[node];
- ans+=x;
- for (int i = 0; i < 30; ++i) {
- mask[i][(x>>i)&1]++;
- }
- for (int ch : adj[node]) if (ch != par && !centroidMarked[ch])
- add(ch, node, x);
- }
- void remove(int node, int par,int x=0) {
- x^=val[node];
- for (int i = 0; i < 30; ++i) {
- mask[i][(x>>i)&1]--;
- }
- for (int ch : adj[node]) if (ch != par && !centroidMarked[ch])
- remove(ch, node,x);
- }
- void solve(int root) {
- //add root
- for (int ch : adj[root])
- if (!centroidMarked[ch]) {
- calc(ch, root);
- add(ch, root, val[root]);
- }
- //TO-DO //remove root
- for (int ch : adj[root])
- if (!centroidMarked[ch])
- remove(ch, root,val[root]);
- }
- public:
- int n, root;
- vector<vector<int>> adj;
- centroid_decomposition(vector<vector<int>> &adj) : adj(adj) {
- n = (int) adj.size() - 1;
- size = vector<int>(n + 1);
- centroidMarked = vector<bool>(n + 1);
- root = decomposeTree(1);
- }
- void get_ans() {
- for (int i = 1; i <=n ; ++i) {
- ans+=val[i];
- }
- cout<< ans;
- }
- };
- int main() {
- boAshraf
- File();
- int t = 1;
- // cin >> t;
- while (t--) {
- sol();
- }
- return 0;
- }
- void sol() {
- int n;
- cin >> n;
- for (int i = 1; i <= n; ++i) {
- cin>>val[i];
- }
- vector<vector<int>>adj(n+1);
- for (int i = 0; i < n - 1; ++i) {
- int u,v;cin>>u>>v;
- adj[u].push_back(v);
- adj[v].push_back(u);
- }
- centroid_decomposition C(adj);
- C.get_ans();
- }
- void File() {
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- }
Advertisement
Add Comment
Please, Sign In to add comment