题目大意
给出一棵n个节点的带点权树,要求实现
- 将x到
y 路径上的所有点的权值都加c - 询问
x 到y路径上所有点的权值的最大公约数。
思路
首先有一个比较显然的结论
gcd(a1,a2,...,an)=gcd(a1,|a2−a1|,...,|an−an−1|)
其中∀i>1,ai≠ai−1
我们只需要证明n=2时成立,剩下的就可以用归纳法证明了。
设g=gcd(a,b),不失一般性地,我们令a<b
那么a,b可以写成a=k1g,b=k2g
则b−a=(k2−k1)g,也就是说g|(b−a)
接下来我们需要证明不存在比g更大的公约数。
假设
那么
于是a,(b−a)分别可以写成
a=k3g′,(b−a)=k4g′
则b=a+(b−a)=(k3+k4)g′
b也是
因此当n=2时得证,当n>2时归纳地证明即可。
有了这个结论这个问题就可以得到化简了。我们不妨先看一下这个问题在链上的情况。
我们不妨用线段树来维护原序列的数,以及差分序列每个区间的最大公约数。那么对于查询操作我们只需要查询开头节点的权值以及某一段的差分的最大公约数即可即可。对于修改操作,对于点的权值的维护就是简单的区间加法了,对于差分的维护我们只需要修改对应区间的头尾两个点即可。
既然这个问题在链上可以简单地解决,我们可以借助树链剖分将链的情况拓展到树上。对于每条重链上我们用维护链的方式来维护,而查询或修改的时候分开为若干条重链,用维护链的方式分别修改每段重链上的线段树。
但是这里有个新的问题诞生了。假如我们现在需要修改u到
注意到对于原序列的操作只有区间修改和单点查询,使用树状数组可以优化常数。
至此,这个问题大致上就被解决了。
时间复杂度:O(nlog2n)
空间复杂度:O(n)

本文介绍了一种解决树形结构中路径操作与查询问题的方法,利用差分思想简化求解最大公约数的过程,并通过树链剖分和线段树等数据结构优化查询效率。
877

被折叠的 条评论
为什么被折叠?



