[USACO19DEC]Tree Depth P
Posted StaroForgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO19DEC]Tree Depth P相关的知识,希望对你有一定的参考价值。
Tree Depth P
题解
我们先考虑一个点的深度可以以怎样的方式表达出来,很明显,任意一个点的深度就是该点的祖先的个数,
即
d
e
p
u
=
∑
v
=
1
n
[
l
c
a
(
u
,
v
)
=
v
]
dep_{u}=\\sum_{v=1}^{n}[lca(u,v)= v]
depu=∑v=1n[lca(u,v)=v]。
我们考虑一个节点在什么时候会成为另一个节点的祖先,我们的二叉搜索树的建树方法与笛卡尔树的建树方法很小,引用结论,其实不知道结论也很容易猜出来, 当
∀
i
∈
[
u
,
v
)
,
a
i
>
a
v
\\forall i\\in[u,v),a_{i}> a_{v}
∀i∈[u,v),ai>av,
a
v
a_{v}
av可以成为
u
u
u的祖先。
所以我们要求的是对于数对
(
u
,
v
)
(u,v)
(u,v),我们不妨设
u
⩽
v
u\\leqslant v
u⩽v,满足
min
i
=
u
v
a
i
>
a
v
\\min_{i=u}^{v}a_{i}>a_{v}
mini=uvai>av,且逆序对数的序列数为
k
k
k的序列数。
我们先考虑构造一个长度为
n
n
n的逆序对数为
k
k
k的序列的方法数。
如果我们已经有了一个长度为
n
−
1
n-1
n−1的排列,我们在排列后面加一个数,再将前面的排列已某种方式离散,那么我们新加入的数产生的逆序对数的范围为
[
0
,
n
−
1
]
[0,n-1]
[0,n−1],且在前面排列固定的情况下,我们加入的数产生的逆序对数与我们加入的数是一一对应的。
通过上面的方法,容易得到我们的
d
p
dp
dp转移式:
d
p
i
,
j
=
∑
k
=
0
i
−
1
d
p
i
−
1
,
j
−
k
dp_{i,j}=\\sum_{k=0}^{i-1}dp_{i-1,j-k}
dpi,j=k=0∑i−1dpi−1,j−k
但我们还有条件是
a
v
a_{v}
av是区间
[
u
,
v
]
[u,v]
[u,v]中最小的,这也就相当于钦定了
a
v
a_{v}
av在
[
u
,
v
]
[u,v]
[u,v]中的逆序对数量。
原来的序列
d
p
dp
dp我们是从
1
1
1一直转移到
n
n
n的,也就是在位置
1
,
2
,
3
,
.
.
.
,
n
1,2,3,...,n
1,2,3,...,n上添加数。
我们可以考虑换一种顺序调价数,先添加
[
u
,
v
)
[u,v)
[u,v),再添加
v
v
v,最后添加
[
1
,
n
]
−
[
u
,
v
]
[1,n]-[u,v]
[1,n]−[u,v]。
所以我们的
d
p
dp
dp式应是
d
p
i
,
j
=
{
d
p
i
−
1
,
j
[
i
=
u
−
v
+
1
]
∑
k
=
0
i
−
1
d
p
i
−
1
,
j
−
k
[
i
≠
u
−
v
+
1
]
dp_{i,j}=\\left\\{\\begin{array}{c} dp_{i-1,j} & [i=u-v+1] \\\\ \\sum_{k=0}^{i-1}dp_{i-1,j-k} & [i\\not =u-v+1]\\end{array}\\right .
dpi,j={dpi−1,j∑k=0i−1dpi−1,j−k[i=u−v+1][i=u−v+1]
由于对于所有的
(
u
,
v
)
(u,v)
(u,v)的
u
−
v
+
1
u-v+1
u−v+1共有
n
n
n种,如果我们要对每一个
u
−
v
+
1
u-v+1
u−v+1都跑一遍的话那就是
O
(
n
2
k
)
O\\left(n^2k\\right)
O(n2k),不
T
T
T飞才怪。
考虑优化。
这式子长得一副可以生成函数优化的样子,设
f
i
(
x
)
=
∏
j
=
1
i
−
1
(
1
+
x
+
.
.
.
+
x
j
)
∏
j
=
i
+
1
n
(
1
+
x
+
.
.
.
+
x
j
)
=
∏
j
=
1
∧
j
≠
x
n
1
−
x
j
+
1
1
−
x
f_{i}(x)=\\prod_{j=1}^{i-1}(1+x+...+x^{j})\\prod_{j=i+1}^{n}(1+x+...+x^j)=\\prod_{j=1\\wedge j\\not = x}^{n}\\frac{1-x^{j+1}}{1-x}
fi(x)=j=1∏i−1(1+x+...+xj)j=i+1∏n(1+x+...+xj)=j=1∧j=x∏n1−x1−xj+1
你当然可以用分治
N
T
T
NTT
NTT什么去算,不过这样太麻烦了,我们只需要知道
[
x
k
]
f
x
(
i
)
[x^k]f_{x}(i)
[xk]fx(i)。
当然,我们不看后面的式子,只看前面那个,我们明显是可以用背包的形式加前缀和优化处理得到的。
我们可以用前缀后缀的方法处理得到
∏
j
=
1
i
−
1
(
1
+
x
+
.
.
.
+
x
j
)
\\prod_{j=1}^{i-1}(1+x+...+x^j)
∏j=1i−1(1+x+以上是关于[USACO19DEC]Tree Depth P的主要内容,如果未能解决你的问题,请参考以下文章
USACO 2004 DEC网络破坏Tree Cutting(DFS)
BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏