AhmedAshraff

Untitled

Oct 30th, 2024
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.58 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define boAshraf ios_base::sync_with_stdio(false); cin.tie(NULL);
  3. #define ll long long
  4. #define sz(s) (int)(s).size()
  5. #define all(s) (s).begin(),(s).end()
  6. using namespace std;
  7. void File();
  8. void sol();
  9. const int N=1e5+5,M=30;
  10. int val[N],mask[M][2];
  11. class centroid_decomposition {
  12.     vector<bool> centroidMarked;
  13.     vector<int> size;
  14.     ll ans=0;
  15.     void dfsSize(int node, int par) {
  16.         size[node] = 1;
  17.         for (int ch : adj[node])
  18.             if (ch != par && !centroidMarked[ch]) {
  19.                 dfsSize(ch, node);
  20.                 size[node] += size[ch];
  21.             }
  22.     }
  23.     int getCenter(int node, int par, int size_of_tree) {
  24.         for (int ch : adj[node]) {
  25.             if (ch == par || centroidMarked[ch]) continue;
  26.             if (size[ch] * 2 > size_of_tree)
  27.                 return getCenter(ch, node, size_of_tree);
  28.         }
  29.         return node;
  30.     }
  31.     int getCentroid(int src) {
  32.         dfsSize(src, -1);
  33.         int centroid = getCenter(src, -1, size[src]);
  34.         centroidMarked[centroid] = true;
  35.         return centroid;
  36.     }
  37.     int decomposeTree(int root) {
  38.         memset(mask,0,sizeof mask);
  39.         root = getCentroid(root);
  40.         solve(root);
  41.         for (int ch : adj[root]) {
  42.             if (centroidMarked[ch])
  43.                 continue;
  44.             int centroid_of_subtree = decomposeTree(ch);
  45.         }
  46.         return root;
  47.     }
  48.     void calc(int node, int par, int x=0) {
  49.         x^=val[node];
  50.         for (int i = 0; i < M; ++i) {
  51.             ans+=(1ll<<i)*mask[i][((x>>i)&1)^1];
  52.         }
  53.         for (int ch : adj[node]) if (ch != par && !centroidMarked[ch])
  54.                 calc(ch, node);
  55.     }
  56.     void add(int node, int par, int x=0) {
  57.         x^=val[node];
  58.         ans+=x;
  59.         for (int i = 0; i < 30; ++i) {
  60.             mask[i][(x>>i)&1]++;
  61.         }
  62.         for (int ch : adj[node]) if (ch != par && !centroidMarked[ch])
  63.                 add(ch, node, x);
  64.     }
  65.     void remove(int node, int par,int x=0) {
  66.         x^=val[node];
  67.         for (int i = 0; i < 30; ++i) {
  68.             mask[i][(x>>i)&1]--;
  69.         }
  70.         for (int ch : adj[node]) if (ch != par && !centroidMarked[ch])
  71.                 remove(ch, node,x);
  72.     }
  73.     void solve(int root) {
  74.         //add root
  75.         for (int ch : adj[root])
  76.             if (!centroidMarked[ch]) {
  77.                 calc(ch, root);
  78.                 add(ch, root, val[root]);
  79.             }
  80.         //TO-DO //remove root
  81.         for (int ch : adj[root])
  82.             if (!centroidMarked[ch])
  83.                 remove(ch, root,val[root]);
  84.     }
  85. public:
  86.     int n, root;
  87.     vector<vector<int>> adj;
  88.     centroid_decomposition(vector<vector<int>> &adj) : adj(adj) {
  89.         n = (int) adj.size() - 1;
  90.         size = vector<int>(n + 1);
  91.         centroidMarked = vector<bool>(n + 1);
  92.         root = decomposeTree(1);
  93.     }
  94.     void get_ans() {
  95.         for (int i = 1; i <=n ; ++i) {
  96.             ans+=val[i];
  97.         }
  98.         cout<< ans;
  99.     }
  100. };
  101.  
  102. int main() {
  103.     boAshraf
  104.     File();
  105.     int t = 1;
  106. //    cin >> t;
  107.     while (t--) {
  108.         sol();
  109.     }
  110.     return 0;
  111. }
  112.  
  113. void sol() {
  114.     int n;
  115.     cin >> n;
  116.     for (int i = 1; i <= n; ++i) {
  117.         cin>>val[i];
  118.     }
  119.     vector<vector<int>>adj(n+1);
  120.     for (int i = 0; i < n - 1; ++i) {
  121.         int u,v;cin>>u>>v;
  122.         adj[u].push_back(v);
  123.         adj[v].push_back(u);
  124.     }
  125.     centroid_decomposition C(adj);
  126.     C.get_ans();
  127. }
  128.  
  129. void File() {
  130. #ifndef ONLINE_JUDGE
  131.     freopen("input.txt", "r", stdin);
  132.     freopen("output.txt", "w", stdout);
  133. #endif
  134. }
  135.  
Advertisement
Add Comment
Please, Sign In to add comment