专栏文章
AT_abc201_e [ABC201E] Xor Distances 题解
AT_abc201_e题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mir3gc7x
- 此快照首次捕获于
- 2025/12/04 15:08 3 个月前
- 此快照最后确认于
- 2025/12/04 15:08 3 个月前
题目大意:
给定一颗带边权无根树,定义 表示 两点在树上的最短路径中所有边权异或的值。求:
思路:
首先明确一点,即:
因为两者的公共部分由于异或而抵消了。
那我们可以先预处理出来根节点到每一个节点的权值,即 。接着我们按位考虑,假设第 位的某一段有贡献,那只可能是 ,那要得到这个贡献必须是 。我们要求所有有贡献的段,考虑如何计算,先统计 的个数设为 ,,则 的个数为 那可以产生贡献的段的贡献和即为 ,别忘了我们每次只枚举第 位,所以最终:
即为所求。另注意取模。
代码:
CPP
#include<bits/stdc++.h>
#define int long long
#define Up(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int N=2e5+10,mod=1e9+7;
int n,ans;
struct Edge{
int v,w;
};
vector<Edge> e[N];
int d[N];
void dfs(int u,int fa){
for(auto it:e[u]){
if(it.v==fa) continue;
d[it.v]=d[u]^it.w;
dfs(it.v,u);
}
}
signed main(){
cin.tie(0),cout.tie(0)->sync_with_stdio(0);
cin>>n;
Up(i,1,n-1){
int u,v,w;
cin>>u>>v>>w;
e[u].push_back({v,w});
e[v].push_back({u,w});
}
d[1]=0;
dfs(1,0);
Up(k,0,60){
int cnt=0;
Up(i,1,n) cnt+=((d[i]>>k)&1ll);
cnt%=mod;
ans+=((1ll<<k)%mod)*(cnt*(n-cnt)%mod)%mod;
ans%=mod;
}
cout<<ans<<"\n";
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...