注:此处的树上差分可能和某些树上差分不太一样。
一次考试考了这样一道题目:
给出一棵有(n)个节点的树,边有长度,点有两种颜色,一开始全是白色。
有两个操作:
修改操作:给出一个修改节点(x),将节点(x)染上黑色。
询问操作:给出一个询问节点(x),记所有黑点形成的集合为(S),求(sum_{yin S}F(dist(operatorname{LCA}(x,y))))。
函数(F)定义为:(F(x)=sum_{i=1}^{x}i^k)((k)为常数)。
其中(1le nle 10^5,1le k<P,0le dle 10^7),时限(2s)。
首先考虑如何得到答案,可以设从点(x)到根的路径经过的点依次为为(x_1x_2x_3dots x_y),以它们为根的子树包含的黑点数量为(a_1a_2a_3dots a_y),那么这次查询的答案就是下面几项的累加:
即:
然后两个(F)的差值是固定的,所以可以预处理出来。
对于修改操作,相当于是给点到根路径上的所有点的权值加上一个每个点特定的数。
对于询问操作,相当于询问点到根路径上的所有点权值之和。
树剖即可。
例题:
首先,题目中的询问(sum_{i=l}^rdep[operatorname{LCA}(i,z)])可以拆成两个询问:
考虑离线处理,排序后,一个一个点地加入,同时在加入的过程中询问。
上一题的弱化版?
k次方直接前缀和处理。
考试题:
给定一棵(n)个节点的树,边有长度,两种操作:修改边权;查询编号在([L,R])之间的节点到节点(x)的路径的长度和。
记节点(x)到根的距离为(dist_x),那么:
所以题目相当于要求:
前两个很好维护,如果忽略修改,最后一个也可以排序后处理,所以关键是如何求出第三个式子。
前面的题目都没有带修改,考虑修改怎么做,由于修改只有一条边,所以可以直接找到线段树上那条边对应的节点修改就好了。
考虑将修改分块,然后在每个块内枚举1到(n)个点,然后再记录一个时间戳表示当前所在的询问编号,对于某个查询,直接将当前时间跳到当前询问的时间戳位置,边跳边修改边权。
若块的数量为(B),节点数和操作数相当,所以时间复杂度就是(O(Bnlog_2^2n+n^2log_2n/B))。
处理后就是P4211 [LNOI2014]LCA的强制在线版本。
强制在线怎么写?考虑到离线时我们是一个一个点加的,加入一个点相当于是修改了一条链,在线段树上修改了(log_2n)个区间,考虑直接维护每个点加入后的信息,用可持久化线段树即可,空间复杂度(O(nlog_2^2n))。
话说这样题目中这个树所有顶点的度数都小于或等于 3 这个条件就没用了欸
感觉这类差分可能算是一种套路吧,所以把它写了下来。
另:把分块那题和可持久化线段树那题套在一起,分块加主席树,又是一道好题(滑稽