AhmedAshraff

Untitled

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