第五届新疆省ACM-ICPC程序设计竞赛(重现赛)-J-异或的路径

链接:https://ac.nowcoder.com/acm/contest/911/J
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

给一棵 n 个点的树,1 号节点为根,边有边权,令 f(u,v) 表示 u 节点到 v 节点,路径上边权异或值。求 ∑ni=1∑nj=1f(i,j)∑i=1n∑j=1nf(i,j),结果对 1000000007 取模。

输入描述:

第一行一个整数 n(n≤100000)n(n≤100000),接下来 n-1 行,第 i 行输入两个整数,p[i](p[i] < i), v[i](100000>=v[i]>=1)   (分别表示 i+1号节点的父亲,以及 i+1 与 p[i] 相连的边的权值。

输出描述:

输出一个整数表示答案。

示例1

输入

复制

3
1 1
1 1

输出

复制

4

示例2

输入

复制

5
1 1
2 2
3 3
4 4

输出

复制

60

备注:

样例 1,f(1,2)=f(2,1)=f(1,3)=f(3,1)=1,f(1,1)=f(2,2)=f(3,3)=f(2,3)=f(3,2)=0

地址:https://ac.nowcoder.com/acm/contest/911/J

思路:树状DP异或

大佬博客:https://blog.csdn.net/kuronekonano/article/details/80786659https://blog.csdn.net/kuronekonano/article/details/80786659

 

Code:

#include<iostream>
#include<vector>
using namespace std;
typedef long long LL;
typedef pair<int,int> pr;

const int MAX_N=1e5+5;
const LL MOD=1e9+7;
int n;
vector<pr> e[MAX_N];
LL d[MAX_N],ss[35];

void DFS(int u,int pre);
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	int u,w;
	for(int i=2;i<=n;++i)
	{
		cin>>u>>w;
		e[u].push_back({i,w});
		e[i].push_back({u,w});
	}
	DFS(1,0);
	LL ans=0,p=1;
	for(int i=0;i<21;p*=2,++i)
		ans=(ans+2*p*ss[i]%MOD*(n-ss[i])%MOD)%MOD;
	cout<<ans<<endl;
	
	return 0;
}

void DFS(int u,int pre)
{
	int v,w;
	for(auto c:e[u])
		if(c.first!=pre){
			v=c.first;	w=c.second;
			d[v]=d[u]^w;
			DFS(v,u);
		}
	for(int i=0,p=1;i<21;p*=2,++i)
		if(d[u]&p)	++ss[i];
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值