To_Heart—总结——点分治

哈哈哈哈没想到吧学了四年OI年点分治都不会!

主要记录一下点分治的思路。代码实现能力不行但是一定要锻炼口胡能力!

首先一般实现三个个函数。

开始前先明确用 vis 数组和 fa 节点来确保遍历的是当前子树。

第一个函数是寻找当前子树的根节点。先存一下整个子树的size记作 sum 再利用重心的性质,即重儿子的size>(子树的size/2) 注意这里的儿子包括先前的节点,也就是 (sum-sz[x]) 。

第二个函数是查询&修改,也就是利用先前的信息更新当前的答案。注意到只算不同于当前子树的答案,内部的答案分治下去讨论。也就是先查询再修改。

第三个是递归函数,也是solve主函数,主要是传进当前子树的重心然后查询&修改并向下递归。

注意到很多时候点分治的使用跟距离联系密切,所以还有一个函数在查询&修改中使用,目的是预处理当前子树的dis。

大概的执行思路长这样子:

void solve(int u){
	vis[u] = pd[0] = 1, doit(u);
	Next(i, u){
		int v = e[i].v;
		if(vis[v]) continue;
		dp[0] = n, sum = size[v], root = 0;
		getroot(v, u), solve(root);
	}
}

随便扒的代码。能看懂就行了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值