直接求不太好做,考虑对原问题进行一些转化:
a
n
s
=
∑
S
∈
T
k
t
h
o
f
S
(1)
ans = \sum \limits_{S \in T} kth\ of\ S \tag{1}
ans=S∈T∑kthofS(1)
=
∑
i
=
1
W
i
∑
S
∈
T
[
k
t
h
o
f
S
=
i
]
(2)
= \sum \limits_{i = 1}^{W} i \sum \limits_{S \in T} [kth\ of\ S =i] \tag{2}
=i=1∑WiS∈T∑[kthofS=i](2)
=
∑
i
=
1
W
∑
S
∈
T
[
k
t
h
o
f
S
≥
i
]
(3)
= \sum \limits_{i = 1}^{W} \sum \limits_{S \in T}[kth\ of\ S \ge i] \tag{3}
=i=1∑WS∈T∑[kthofS≥i](3)
=
∑
i
=
1
W
∑
S
∈
T
[
c
n
t
S
[
i
]
≥
K
]
(4)
= \sum \limits_{i = 1}^{W} \sum \limits_{S \in T}[cnt_S[i] \ge K] \tag{4}
=i=1∑WS∈T∑[cntS[i]≥K](4)
T
T
T 表示树上的所有连通块集合。
第
(
2
)
(2)
(2) 步到第
(
3
)
(3)
(3) 步是一个常见的转化:对于布尔表达式
[
k
t
h
o
f
S
≥
i
]
[kth\ of\ S \ge i]
[kthofS≥i],每个布尔表达式
[
k
t
h
o
f
S
=
i
]
[kth\ of\ S = i]
[kthofS=i] 恰好被算了
i
i
i 次。
第
(
4
)
(4)
(4) 步中的
c
n
t
S
[
i
]
cnt_S[i]
cntS[i] 表示连通块
S
S
S 中权值
≥
i
\ge i
≥i 的结点个数。
据此我们可以设
f
[
u
]
[
i
]
[
j
]
f[u][i][j]
f[u][i][j] 表示在以
u
u
u 为根的子树内包含点
u
u
u 且恰好有
j
j
j 个权值
≥
i
\ge i
≥i 的结点的连通块个数。
特别地,我们定义选取的连通块大小为空也是一种方案。
则最后的答案为:
∑
u
=
1
n
∑
i
=
1
W
∑
j
=
K
n
f
[
u
]
[
i
]
[
j
]
\sum \limits_{u = 1}^{n} \sum \limits_{i = 1}^{W} \sum \limits_{j = K}^{n}f[u][i][j]
u=1∑ni=1∑Wj=K∑nf[u][i][j]
转移显然为:
f
[
u
]
[
i
]
[
j
]
=
∏
v
∈
s
o
n
u
f
[
v
]
[
i
]
[
j
v
]
(
d
u
≥
i
,
∑
j
v
≥
0
j
v
=
j
−
1
)
f[u][i][j] = \prod \limits_{v \in son_u} f[v][i][j_v](d_u \ge i, \sum \limits_{j_v \ge 0} j_v = j - 1)
f[u][i][j]=v∈sonu∏f[v][i][jv](du≥i,jv≥0∑jv=j−1)
f
[
u
]
[
i
]
[
j
]
=
∏
v
∈
s
o
n
u
f
[
v
]
[
i
]
[
j
v
]
(
d
u
<
i
,
∑
j
v
≥
0
j
v
=
j
)
f[u][i][j] = \prod \limits_{v \in son_u} f[v][i][j_v](d_u < i, \sum \limits_{j_v \ge 0} j_v = j)
f[u][i][j]=v∈sonu∏f[v][i][jv](du<i,jv≥0∑jv=j)
初值
f
[
u
]
[
i
]
[
[
d
u
≥
i
]
]
=
1
f[u][i][\ [d_u \ge i]\ ] = 1
f[u][i][[du≥i]]=1,每次枚举子节点
v
v
v 的
j
v
j_v
jv 进行合并。
以
u
u
u 为根的子树转移结束后,因为连通块大小为空也算一种方案,我们要令
f
[
u
]
[
i
]
[
0
]
f[u][i][0]
f[u][i][0] 加一。
时间复杂度
O
(
n
2
W
)
O(n^2 W)
O(n2W),实现时可以把
i
i
i 这一维提到外面枚举,就不需要在状态中记录
i
i
i,只要有足够优秀的常数就能通过所有数据 。
Part 2
考虑复杂度正确的做法,即如何优化 DP 的转移。
容易发现转移是一个卷积的形式,我们设
F
[
u
]
[
i
]
F[u][i]
F[u][i] 表示
f
[
u
]
[
i
]
[
j
]
f[u][i][j]
f[u][i][j] 的生成函数,即:
F
[
u
]
[
i
]
=
∑
j
=
0
n
f
[
u
]
[
i
]
[
j
]
x
j
F[u][i] = \sum \limits_{j = 0}^{n} f[u][i][j] x^j
F[u][i]=j=0∑nf[u][i][j]xj
我们再另外设
G
[
u
]
[
i
]
=
∑
v
∈
s
u
b
t
r
e
e
u
F
[
v
]
[
i
]
G[u][i] = \sum \limits_{v \in subtree_u} F[v][i]
G[u][i]=v∈subtreeu∑F[v][i],答案就变为
G
[
r
o
o
t
]
[
i
]
G[root][i]
G[root][i] (
r
o
o
t
root
root 为我们选定的树根) 的后
n
−
K
+
1
n - K + 1
n−K+1 项的系数之和。
转移:
F
[
u
]
[
i
]
=
x
∏
v
∈
s
o
n
u
F
[
v
]
[
i
]
(
d
u
≥
i
)
F[u][i] = x \prod \limits_{v \in son_u} F[v][i](d_u \ge i)
F[u][i]=xv∈sonu∏F[v][i](du≥i)
F
[
u
]
[
i
]
=
∏
v
∈
s
o
n
u
F
[
v
]
[
i
]
(
d
u
<
i
)
F[u][i] = \prod \limits_{v \in son_u} F[v][i](d_u < i)
F[u][i]=v∈sonu∏F[v][i](du<i)
G
[
u
]
[
i
]
=
F
[
u
]
[
i
]
+
∑
v
∈
s
o
n
u
G
[
v
]
[
i
]
G[u][i] = F[u][i] + \sum \limits_{v \in son_u} G[v][i]
G[u][i]=F[u][i]+v∈sonu∑G[v][i]
同样地,以
u
u
u 为根的子树转移结束后,我们要令
F
[
u
]
[
i
]
F[u][i]
F[u][i] 的常数项加一。
换个思路考虑,多项式点值的加法和乘法运算相当方便。我们把所有
G
[
r
o
o
t
]
[
i
]
G[root][i]
G[root][i] 相加合并为一个多项式。现在我们只要求出这个多项式的
n
+
1
n + 1
n+1 个点值,就可以通过拉格朗日插值公式
O
(
n
2
)
O(n^2)
O(n2) 还原这个多项式的各项系数,从而得到答案。
我们在最外层枚举
x
=
1
→
n
+
1
x = 1 \to n +1
x=1→n+1,那么点值关于
i
i
i 这一维的初值设定就相当于线段树上的区间修改,转移则可以看做多棵线段树的合并。
考虑直接在线段树上打标记维护
F
,
G
F,G
F,G 的点值
(
f
,
g
)
(f, g)
(f,g)。
具体地,我们定义一种对于
(
f
,
g
)
(f, g)
(f,g) 的变换
(
a
,
b
,
c
,
d
)
(a,b,c,d)
(a,b,c,d) 表示把
(
f
,
g
)
(f,g)
(f,g) 变为
(
a
×
f
+
b
,
c
×
f
+
d
+
g
)
(a \times f + b, c \times f + d + g)
(a×f+b,c×f+d+g),直接在线段树上维护这样的标记。
标记的合并如下:
(
a
1
,
b
1
,
c
1
,
d
1
)
+
(
a
2
,
b
2
,
c
2
,
d
2
)
(a_1, b_1, c_1, d_1) + (a_2, b_2, c_2, d_2)
(a1,b1,c1,d1)+(a2,b2,c2,d2)
=
(
a
1
×
a
2
,
a
2
×
b
1
+
b
2
,
a
1
×
c
2
+
c
1
,
b
1
×
c
2
+
d
1
+
d
2
)
= (a_1 \times a_2,a_2 \times b_1 + b_2, a_1 \times c_2 + c_1,b_1 \times c_2 + d_1 + d_2)
=(a1×a2,a2×b1+b2,a1×c2+c1,b1×c2+d1+d2)
则对于每个结点
u
u
u 相当于一开始在
[
1
,
d
u
]
[1, d_u]
[1,du] 打上标记
(
1
,
x
,
0
,
0
)
(1, x, 0, 0)
(1,x,0,0),在
[
d
u
+
1
,
W
]
[d_u + 1, W]
[du+1,W] 打上标记
(
1
,
1
,
0
,
0
)
(1, 1, 0, 0)
(1,1,0,0),转移完后再打上标记
(
1
,
1
,
1
,
0
)
(1, 1, 1, 0)
(1,1,1,0)。