点分治 12

来源:互联网 发布:firefly rk3288 源码 编辑:程序博客网 时间:2024/05/21 16:55

例题 poj1741 tree

Description

给定一棵 n 个顶点的树,边带正权,问你距离不超过 k 的顶点对数。
n105

Solution

这道题就当做点分治讲解吧。

  • 树的重心:如果删除树上一个点 u 后每颗子树的大小都不超过 n2 ,那么称 u 为这棵树的重心。

假设我们按重心把树分成了若干子树,那么所要求得顶点对必居下面三者其一。

  • 1 属于同一子树的顶点对 (v,w) :
    递归下去。
  • 2 属于不同子树的顶点对 (v,w)
    直接对所有点按照距离重心距离排序,然后枚举所有点,二分即可,减去情况 1 中的点对。
  • 3 重心s和其他顶点v组成的顶点对 (s,v)
    额外添加一个距离 s 为零的结点,转化为情况 2

三种点对

然后就没什么好说的,看代码吧。
题解。


例题 bzoj2599 [IOI2011]Race

题解。


例题 bzoj2152 聪聪可可

题解。


例题 hdu4812 D Tree

Description

给定一棵 n 个点的树,每个点有权值 Vi
问是否存在一条路径使得路径上所有点的权值乘积 mod(106+3)K
输出路径的首尾标号,若有多解,输出字典序最小的解

Solution

可以预处理乘法逆元。
记录一个 id 数组,id[x] 代表当前这次分治时,到重心 s 的乘积(不含重心)在模意义下为 x 的点的编号最小是多少
到某个点 U 的时候,如果 id[Kinverse[dis[U]w[s]%MOD]%MOD] 存在,就尝试更新答案。


例题 cdoj1562 Amaz1ng Prime

Description

给定一棵树,边带权( 0 或者 1 ),问你树上有多少条路径满足权值之和为素数。

Solution

tong[i] 表示树上权值和为 i 的路径数量。
dis[u] 表示每点 u 到重心 s 的距离。
tong[i]=f[0]f[x]+f[1]f[x1]+...+f[x]f[0]


例题 bzoj3697 采药人的路径

题解。


点分治总结

对于一般的点分治问题,解决了跨越重心的统计就好了。复杂度是 O(log2n)。附上学长博客。
通过几道点分治例题,已经可以运用简单点分治解决问题。