codeforces766E. Mahmoud and a xor trip(DP)

题意:给定一棵树 每个节点有权值 任意选两个点i和j满足i<=j其贡献为i到j路径所有点的xor和 求所用点对的和

题解:感觉带xor的题从位运算考虑会好很多 于是对于每个点枚举每一位 对于每一位dp[i][0]表示从i点开始这一位xor和为0的路径数 那么dp[i][1]同理

设j为这个点的儿子 那么转移就把他所有儿子的贡献加起来 如果i这一位为0 dp[i][0] += dp[j][0], dp[i][1] += dp[j][1] 为1同理
然后从1开始dfs一遍就可 最开始还奇怪假如1 - 3 - 2这样的图 dfs一遍好像答案不对 然而并不是 这样dfs统计的顺序是3 - 2, 1 - 3, 1 - 3 - 2.  3 - 2和2 - 3是一样的 所以具有正确性,听说这是种套路题.....
             
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll ans;
vector<int> g[100005];
ll q[100005];
ll dp[100005][2];

void dfs(int x, int fa, int pos)
{
    int c = q[x] >> pos & 1;
    dp[x][c] = 1;
    for(int i = 0; i < g[x].size(); i++)
    {
        if(g[x][i] == fa) continue;
        dfs(g[x][i], x, pos);

        ans += (1LL << pos) *  dp[x][1] * dp[g[x][i]][0];
        ans += (1LL <<pos) * dp[x][0] * dp[g[x][i]][1];
        if(c == 0) dp[x][0] += dp[g[x][i]][0], dp[x][1] += dp[g[x][i]][1];
        else dp[x][0] += dp[g[x][i]][1], dp[x][1] += dp[g[x][i]][0];
    }
}

int main()
{
    ans = 0;
    int n; scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%lld", &q[i]), ans += q[i];

    for(int i = 1; i < n; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }

    for(int i = 0; i < 20; i++)
    {
        memset(dp, 0, sizeof(dp));
        dfs(1, 0, i);
    }
    printf("%lld\n", ans);
    return 0;
}


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值