【2018.12.22模拟赛】Party【启发式合并】【数据结构】(无实现)

Description

给出了一棵以1为根的有n个节点的树。
m组询问,每个询问选择一个区间[l,r]。
你需要回答满足 z ∈ [ 1 , n ] z\in [1,n] z[1,n]且存在 x , y ∈ [ l , r ] x,y\in[l,r] x,y[l,r]使得 l c a ( x , y ) = z lca(x,y)=z lca(x,y)=z z z z的个数。
n , m ≤ 3 × 1 0 5 n,m\leq 3\times10^5 n,m3×105

Solution

好题啊

考虑对于一个点,表示出能贡献的区间

对于两个点 x , y , x < y x,y,x<y x,y,x<y,令 z = l c a ( x , y ) z=lca(x,y) z=lca(x,y),那么至少对于所有的 [ l , r ] , l ≤ x , y ≤ r [l,r],l\leq x,y\leq r [l,r],lx,yr,z都是可以贡献的。

先将z本身就在区间 [ l , r ] [l,r] [l,r]中的情况排除

我们可以设法找出所有点对x,y,当然这是不现实的,我们可以考虑只找出极小的点对,即x与y最接近的那些。

这样思路就明朗了,对于每一个z,枚举它子树中的节点p,令它作为上面的y,也就是说只需要找到z的除p所在的子树的其他子树中最大的 q q q满足 q < p q<p q<p,这样就求出了一对点对。

我们发现这样效率很低
考虑启发式合并,即子树大小最大的那个儿子(即轻重链剖分的重儿子)中我们不枚举,只枚举轻儿子,此时不仅要求最大的 q q q满足 q < p q<p q<p,还要求最小的 q ′ q' q满足 q ′ > p q'>p q>p,这个用个set维护一下就好了,合并就启发式暴力合并。

这样我们算出来的点对只有 O ( n log ⁡ n ) O(n\log n) O(nlogn)
考虑计算答案。
扫描线,从小到大枚举询问区间右端点,设 l e f t [ i ] left[i] left[i]表示节点i此时能贡献所有 l ≤ l e f t [ i ] l\leq left[i] lleft[i]的询问,显然它是单调不降的。

我们将点对挂在相应的y处,枚举到就直接改left就行了,询问就用树状数组查询。

总的时间复杂度 O ( n log ⁡ 2 n ) O(n\log ^2 n) O(nlog2n)

你可能感兴趣的:(题解,---数据结构,————树链剖分,————启发式合并,数据结构,set,dsu,on,tree,启发式合并,树链剖分)