ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

点分树学习笔记

2022-02-06 23:01:20  阅读:154  来源: 互联网

标签:log 笔记 点分 学习 leq 点分树 lca 树上 dis


1.0 定义

其实本质也是一种暴力。。

回忆点分治的过程:每次找到当前子树的重心,处理所有经过该重心的路径的答案,然后将其删去,分裂成一些子树,再分别进去递归。

把点分治的过程离线下来,将当前树的重心与上一层的树的重心连边,这样就可以得到一棵树,我们称之为“点分树”。

1.1 应用范围

点分治通常针对树上路径问题,一般是”任意两点间的路径“。

但有时会加上多次询问(并强制在线等),不可能每次都跑一遍点分治。于是我们建出点分树,每次在点分树上求解即可。

1.2 性质

点分树有两个性质:

  • 点分树的树高是\(\log n\)级别的(每次找重心,\(size\)至少减半)。这是一个强有力的性质,我们还可以据此推出点分树上的\(\sum sz_i\)是\(n\log n\)级别的(证明考虑每个点最多对祖先贡献\(\log n\)次)。所以我们可以给每个点开一个包含子树中所有点的vector(或者开到\(dep\)),这样做空间也是能接受的。并且修改操作也可以考虑直接暴跳祖先(总之就是暴力搞)。
  • 对于任意两点\(x,y\),可以确定的是\(x,y\)在点分树上的\(lca \)一定在(原树上)\(u\rightarrow v\)的路径上。这点比较重要,因为据此有\(dis(x,y)=dis(x,lca)+dis(y,lca)\),有时可以转化问题。

1.3 求法

贴一份代码(其实就比点分治过程多了一句话):

void pcalc(int x, int f)
{
	sz[x] = 1;
	for (auto y : g[x]) if (y != f && (!vis[y])) pcalc(y, x), sz[x] += sz[y];
	return;
}

void solve(int x)
{
	vis[x] = 1; pcalc(x, 0);
	for (auto y : g[x])
	{
		if (vis[y]) continue;
		rt = 0, ns = sz[y]; findrt(y, x); 
      	nf[rt] = x; solve(rt);
	}
	return;
}

1.4 例题

点分树 | 震波

借这道题说一说点分树的一般套路。

按照上面的性质,把所有的\(y\)按照和\(x\)(在点分树上)的\(lca\)分类(最多有\(\log n\)种),有

\[res=\sum\limits_{dis(x,y)\leq k}a_y=\sum\limits_{dis(x,z)+dis(z,y)\leq k \land lca(x,y)=z}a_y=\sum\limits_{dis(z,y)\leq k-dis(x,z) \land LCA(x,y)=z}a_y \]

满足\(lca(x,y)=z\)的\(y\)即为\(z\)的子树抠掉\(z\) 在 \(x\) 方向上的儿子 \(s\) 的子树后剩下的部分。所以答案即为 \(z\)的子树内到 \(z\)的距离\(\leq k−dis(x,z)\) 的点权和减去\(s\)子树内到 \(s\) 的距离\(\leq k−dis(x,z)\) 的点权和(容斥思想)。给每个点开一个树状数组,下标为\(i\)的位置维护 \(x\) 子树内所有 \(dis(x,y)=i\) 的\(a_y\) 的和,从而下标只要开到\(maxdep\)范围,防止\(\rm MLE\)。

特别注意,除了维护上述贡献外,还要维护\(x\)对\(fa_x\)的贡献。切记不能只维护一个,然后在 \(s\)对应的线段树上查 \(\leq k−dis(x,z)−1 \)的和,因为点分树上的\(x\)和\(fa_x\)基本没有关系。

1.5 总结

基本上是对每个点\(x\)维护它子树内的所有点对它的贡献和它们对\(fa_x\)的贡献(用来去重)。基本都要带上一些数据结构,复杂度一般是\(\mathcal{O}(n\log^2n)\)。

标签:log,笔记,点分,学习,leq,点分树,lca,树上,dis
来源: https://www.cnblogs.com/andysj/p/15866574.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有