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+1,M=30;
- int freq[M][2]{};
- int mask[M][2]{};
- int val[N];
- class centroid_decomposition {
- vector<bool> centroidMarked;
- vector<int> size;
- 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;
- }
- void add(int x){
- for (int i = 0; i < M; ++i) {
- freq[i][(x>>i)&1]++;
- }
- }
- void collect(int node, int par, int x = 0) {
- add(x);
- for (int ch: adj[node])
- if (ch != par && !centroidMarked[ch]) {
- collect(ch, node, x ^ val[ch]);
- }
- }
- void calc(int x) {
- ans+=x;
- for (int i = 0; i < M; ++i) {
- if((x>>i)&1)swap(freq[i][0],freq[i][1]);
- ans+=(1ll<<i)*freq[i][1];
- ans+=(1ll<<i)*(freq[i][1]*mask[i][0]);
- ans+=(1LL<<i)*(freq[i][0]*mask[i][1]);
- if((x>>i)&1)swap(freq[i][0],freq[i][1]);
- }
- for (int i = 0; i < M; ++i) {
- mask[i][0]+=freq[i][0];
- mask[i][1]+=freq[i][1];
- }
- }
- int decomposeTree(int root) {
- memset(mask,0,sizeof mask);
- root = getCentroid(root);
- for (int ch : adj[root]) {
- if (centroidMarked[ch])
- continue;
- memset(freq, 0, sizeof(freq));
- collect(ch,root,val[ch]);
- calc(val[root]);
- }
- for(auto ch:adj[root]){
- if (centroidMarked[ch])
- continue;
- decomposeTree(ch);
- }
- return root;
- }
- public:
- int n, root;
- ll ans=0;
- 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() const{
- cout<<ans<<'\n';
- }
- };
- int main() {
- boAshraf
- File();
- int t = 1;
- // cin >> t;
- while (t--) {
- sol();
- }
- return 0;
- }
- void sol() {
- int n;
- cin>>n;
- vector<vector<int>>adj(n+1);
- for (int i = 1; i <= n; ++i) {
- cin>>val[i];
- }
- 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();
- }
- 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