【总结】点分治杂题

bzoj2566

点分树:维护每颗子树内所有相同颜色点到根距离的最小值+次小值。
再维护一个全局的最小答案。都可以套multiset(注意multiset直接删除一个值时是将所有这个值都删掉,只删除一个要用指针)


hdu5571

拆位&点分树:
对于每个分治中心,维护管辖子树内0和1的个数及距离和以及它的每个儿子结点子树内0和1的个数及距离和(容斥用)。


hdu5227

单个四元组可以看做一堆石子,它的石子数就是它的字典序大小(每次可以拿任意个)。同样一条路径可以看做Nim游戏。
问题转成了求石子数异或和为0的总路径数,点分治即可。

关键在于求四元组 ( a , b , c , d ) (a,b,c,d) (a,b,c,d)的字典大小:

第一位不同:
∑ t = 1 a − 1 ∑ i = 1 t ∑ j = 1 t gcd ⁡ ( i , j ) \quad \sum\limits_{t=1}^{a-1} \sum\limits_{i=1}^t \sum\limits_{j=1}^t\gcd (i,j) t=1a1i=1tj=1tgcd(i,j)
= ∑ t = 1 a − 1 ∑ i = 1 t φ ( i ) ⌊ t i ⌋ 2 =\sum\limits_{t=1}^{a-1}\sum\limits_{i=1}^t\varphi (i)\lfloor\dfrac {t}{i}\rfloor^2 =t=1a1i=1tφ(i)it2

可以对 1 ≤ a ≤ 1000 1\leq a\leq 1000 1a1000统一 n \sqrt n n 预处理。

第二位不同:
∑ t = 1 b − 1 ∑ i = 1 a gcd ⁡ ( t , i ) \quad \sum\limits_{t=1}^{b-1}\sum\limits_{i=1}^a \gcd(t,i) t=1b1i=1agcd(t,i)
= ∑ t = 1 min ⁡ ( b − 1 , a ) φ ( t ) ⌊ b − 1 i ⌋ ⌊ a i ⌋ =\sum\limits_{t=1}^{\min(b-1,a)}\varphi (t)\lfloor\dfrac {b-1}{i}\rfloor\lfloor\dfrac{a}{i}\rfloor =t=1min(b1,a)φ(t)ib1ia

第三位不同:
∑ i = 1 c − 1 gcd ⁡ ( b , i ) \sum\limits_{i=1}^{c-1}\gcd(b,i) i=1c1gcd(b,i)
= ∑ i ∣ b φ ( i ) ⌊ c − 1 i ⌋ =\sum\limits_{i|b}\varphi (i)\lfloor\dfrac{c-1}{i}\rfloor =ibφ(i)ic1

第四位不同:
max ⁡ ( d − 1 , 0 ) \max(d-1,0) max(d1,0)


codechef-BTREE

题解

总询问点数 ≤ 500000 ≤ 500000 500000明示建虚树。
对于每个点,首先在点分树内算出单点贡献,再建出虚树容斥,对于每条存在重复计算点的边 ( u , v ) (u,v) (u,v)

二分出中点 z z z,使得 r u − d i s ( u , z ) = r v − d i s ( v , z ) r_u-dis(u,z)=r_v-dis(v,z) rudis(u,z)=rvdis(v,z)
那么在 u , v u,v u,v共同覆盖的区域内从 u u u一边出发:跨过 z z z v v v u u u优,未跨过时 u u u v v v优。删去 z z z能覆盖的范围的点(这部分被算了2次)。

p.s
为了避免 z z z在边上的情况,可以在所有边上都建一个虚点。


codechef-PRIMEDST

点分治:每个子集直接记录记录距离分治中心 k k k的点数 f k f_k fk,构造 f k f_k fk的生成函数直接卷积就得到了经过分治中心长度为 k k k的路径数,找到素数直接统计即可。

什么? f k f_k fk和子集卷积会算重? 2 k 2k 2k里面只有 2 2 2是质数,特判一下即可。


CF150E.Freezing with Style

求中位数直接套路二分把 ≥ m i d \geq mid mid的边权看做1, < m i d <mid <mid的看做-1,找是否存在一条总权 ≥ \geq 的边。

处理子数信息需要单调队列和前缀和优化使得总复杂度降到 O ( n log ⁡ 2 n ) O(n\log ^2 n) O(nlog2n)(二分套点分治)。


CFgym100633D.LWDB

点分树,每个分治中心维护一个单调栈( d d d递减,颜色不同,并维护时间戳)

每次查询 x x x暴力跳点分树,跳到 y y y时,二分出单调栈内最小的满足 d ≥ d i s t ( x , y ) ) d\geq dist(x,y)) ddist(x,y)的点的颜色,取时间戳最大的。


小结

求解有根树问题基本上都可以多个 log ⁡ \log log转成求解无根树所有点的答案。

路径问题都可以套点分治。

在线问题点分树,离线下来点分治。

点分治维护信息往往可以优化到 n log ⁡ n n\log n nlogn或线性,存在一些常见套路(可以套很多东西(单调队列,BIT…),也有很多东西可以套点分治(二分,拆位))。
注意复杂度。

点分治序也是个好东西。

你可能感兴趣的:(点分治,点分树)