• [CF766E] Mahmoud and a xor trip


    [CF766E] Mahmoud and a xor trip - 树形dp

    Description

    求所有点对路径上所有点权值的异或和的和

    Solution

    按位拆分处理,统计子树内直链异或为 0,1 的条数,然后在 LCA 处求贡献

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int n;
        cin >> n;
        vector<int> a(n + 2);
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        vector<vector<int>> g(n + 2);
        for (int i = 1; i < n; i++)
        {
            int t1, t2;
            cin >> t1 >> t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        int ans = 0;
        vector<vector<int>> f(n + 2, vector<int>(2));
        function<void(int, int, int)> dfs = [&](int p, int from, int bt) -> void {
            int s0 = 0, s1 = 0, s00 = 0, s01 = 0, s11 = 0;
            f[p][0] = f[p][1] = 0;
            for (int i = 0; i < g[p].size(); i++)
            {
                int q = g[p][i];
                if (q == from)
                    continue;
                dfs(q, p, bt);
                f[p][0] += f[q][0];
                f[p][1] += f[q][1];
                s0 += f[q][0];
                s1 += f[q][1];
                s00 += f[q][0] * f[q][0];
                s11 += f[q][1] * f[q][1];
                s01 += f[q][0] * f[q][1];
            }
            f[p][0]++;
            if ((a[p] >> bt) & 1)
            {
                ans += ((s0 * s0 + s1 * s1 - s00 - s11) / 2 + s0 + 1) << bt;
                swap(f[p][0], f[p][1]);
            }
            else
            {
                ans += (s0 * s1 - s01 + s1) << bt;
            }
        };
        for (int i = 0; i < 22; i++)
            dfs(1, 0, i);
        cout << ans << endl;
    }
    
    
  • 相关阅读:
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
    学习进度条
    软件工程练习——买书
    软件工程练习——找水王2
    Java作业07
    Java课堂作业06
    读《大道至简》第六章有感
    Java课堂作业05
  • 原文地址:https://www.cnblogs.com/mollnn/p/14412848.html
Copyright © 2020-2023  润新知