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);
}
}
随便扒的代码。能看懂就行了。