题意:
给定一棵树.
询问给定 b , k b,k b,k,现在要选择离 b b b距离 ≤ k \le k ≤k单位的点 a a a和无限制的 c c c,使得 a , b a,b a,b都是 c c c的祖先.
问总选择方案数.
n , q ≤ 3 e 5 n,q\le 3e5 n,q≤3e5
有两种实现方法:
一开始脑抽写了一个以
b
,
c
b,c
b,c为中心的
d
p
dp
dp.
具体我们考虑固定一个
c
c
c的代价:
min
(
d
e
p
[
b
]
−
1
,
k
)
+
min
(
d
e
p
[
c
]
−
d
e
p
[
b
]
−
1
,
k
)
\min(dep[b]-1,k)+\min(dep[c]-dep[b]-1,k)
min(dep[b]−1,k)+min(dep[c]−dep[b]−1,k).(即考虑
a
a
a是否为
b
b
b的祖先)
然后我们发现前面可以快速计算,后面实际上维护一个后缀和就好了.
c
o
d
e
code
code
然后,看到一个更加简单的做法:
考虑后面一部分,如果我们以
a
a
a为中心,那么代价为
s
z
[
a
]
−
1
sz[a]-1
sz[a]−1.
所以我们直接按深度维护
s
z
[
a
]
−
1
sz[a]-1
sz[a]−1的和即可.
啊,你问我为啥维护后缀和?
因为维护后缀和在合并的时候只需要
l
e
n
[
y
]
len[y]
len[y]的循环次数,
而前缀和要
l
e
n
[
x
]
len[x]
len[x]次.(
l
e
n
[
x
]
len[x]
len[x]为从
x
x
x出发的最长链,
y
∈
s
o
n
x
y\in son_x
y∈sonx)
这样总复杂度就线性啦~~