【题解】CF575B Bribes

由题可知这是一棵树,因此求每一条边经过的次数可以通过树上差分解决。而现在只有部分(有向)边需要花费,因此就需要找到一种能够记录单向花费的信息。考虑到一条边连接的两个点因在树上而深度不同,所以可以分为叶子指向父节点与父节点指向叶子两种边。形象化地,第一种可以称为上行边,第二种称为下行边。

首先通过树上差分,将信息分别储存在上行边的起点与下行边的中点。

for (int i = 1;i <= k;++i)
{
   
   
	int lca = getLCA (a[i],a[i - 1]);
	++up[a[i - 1]];++down[a[i]];//up 加的位置为起点,down 加的位置为终点
	--up[lca];--down[lca];
} 

然后通过一次 dfs 和差分数组还原每一条边经过的次数。最后统计答案,对于一条 v→uv \to uvu 需要花费的边,若是上行边,那么通过的次数记录在 vvv 上,否则是 uuu 上。设某条边经过了 xxx 次,则总花费为 1+2+⋯+2x−1=2x−11 + 2 + \cdots + 2^{x - 1} = 2^x - 11+2++2x1=2x1,所以直接预处理 222 的幂次即可。

总代码如下:

#include <iostream>
#include <cstdio>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值