点分治
博客:https://blog.csdn.net/u010660276/article/details/44920725
论文:https://wenku.baidu.com/view/8861df38376baf1ffc4fada8.html?re=view
博客:https://blog.csdn.net/wu_tongtong/article/details/79790268
适合题型:求条件下符合点的对数
点分治就是每次找到重心,然后把重心去掉,对分成的每两棵树之间分别统计路径信息(以重心的每个相邻点为根,遍历整棵子树即可得到这个根到每个结点的统计信息),就可以知道包含这个重心的所有路径的信息,然后对于剩下的路径就是在子树里面进行同样的操作了,直到只剩一个点为止(注意这一个点所构成的路径有时也要处理一下)。边分治就是每次找到一条边,使得删掉这条边后分成的两棵子树大小尽可能平均,然后以删掉的边的两端点为根,分别统计根到两棵树中的每个结点的路径信息,最后合并算路径,即可得到包含这条边的所有路径的信息,剩下的路径在两棵树中递归处理。
POJ1741 Tree
题意:一颗树 每个边有个权值 求u,v点权值小于等于k的对数
思路:满足要求的点对,有二种可能1:过根节点p,2:不过根节点p
1: 对于过根节点的那种情况,我们可以求出每个点到根节点的距离 如果我们把这些距离用一个数组存起来,问题就转换成了在一个数组中取二个数,他们的和小于等于k,这样就可以先排序 然后用一个l,r表示最左边和最右边坐标,如果a[l]+a[r]<=k那么 a[l]+a[m]一定小于等于k(l<m<r)直接累加答案即可,这样就可以o(n)解决一个数组中取二个数,他们的和小于等于k
2:对于不过根节点的情况,那么那二个节点一定在根节点的一个儿子节点为根节点的子树中,这样我们可以直接往下递归处理,转换成新的情况;
bzoj 2152 聪聪可可
题意:一颗树,每个边有个权值,求u,v二点路径边权和模3的个数ans 输出 ans与n*n的最简分数形式
思路:用点分治模板, 链上 num[0]*num[0]+num[1]*num[2]+num[2]*num[1]就是答案
HYSBZ 1316 树上的询问
题意:一颗树,每个边有个权值,q个询问,每个询问是否存在u,v二个点之间 的边权和等于q[i],(q[i]可以为0)
思路:点分治判断的是符合条件的路径个数,那么就求路径权值和为q[i]的路径数是否大一1;因为q只有100,可以先将询问读入,在点分治的时候处理每个询问,用点分治模板可以将问题转化为,有一个数组,判断二个数他们的和为k 的个数,二分即可;特别注意 q[i]可以为0,特判这种情况总是成立即可;