c/c++语言开发共享nowcoder911J 异或的路径

题目链接 题意 给出一棵树,每条边有边权。求$sumlimits_{i=1}^n{f(i,j)}$,$f(i,j)$表示从i到j路径的异或和。 思路 $g_i$表示从根到$i$的异或和,两点之间的路径异或和就可以用$g_i otimes g_j$表示。 先然$g_i$可以一次$dfs$求出来。 …

题目链接

题意

给出一棵树,每条边有边权。求(sumlimits_{i=1}^n{f(i,j)}),(f(i,j))表示从i到j路径的异或和。

思路

(g_i)表示从根到(i)的异或和,两点之间的路径异或和就可以用(g_i otimes g_j)表示。

先然(g_i)可以一次(dfs)求出来。然后就是统计答案。按位考虑,每一位的数量是当前位置为0的个数与1的个数的成绩,再乘以当前位置的贡献即可。

代码

/* * @author: wxyww * @date:   2019-06-05 07:59:07 * @last modified time: 2019-06-05 08:30:46 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<ctime> using namespace std; typedef long long ll; const int n = 100000 + 100,mod = 1000000007; ll read() {     ll x=0,f=1;char c=getchar();     while(c<'0'||c>'9') {         if(c=='-') f=-1;         c=getchar();     }     while(c>='0'&&c<='9') {         x=x*10+c-'0';         c=getchar();     }     return x*f; } int f[2][100],b[n]; struct node {     int u,v,w,nxt; }e[n]; int ejs,head[n]; void add(int u,int v,int w) {     e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].w = w; } void dfs(int u) {     for(int i = head[u];i;i = e[i].nxt) {         int v = e[i].v;         b[v] = b[u] ^ e[i].w;         dfs(v);     } } void solve(int x) {     for(int i = 0;i <= 20;++i) f[(x >> i) & 1][i]++; } int main() {     int n = read();     for(int i = 2;i <= n;++i) {         int u = read(),w = read();         add(u,i,w);     }     dfs(1);     ll ans = 0;     for(int i = 1;i <= n;++i) solve(b[i]);     for(int i = 0;i <= 20;++i)         ans += 1ll * f[0][i] * f[1][i] % mod * (1 << i) % mod,ans %= mod;     cout<<ans * 2 % mod;      return 0; }

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/603143.html

(0)
上一篇 2021年5月11日
下一篇 2021年5月11日

精彩推荐