QDEZ 2023NOIP模拟赛1 T3
原题面
题目简述
给定一颗n个点的完全二叉树 , 每个点有点权 , 规定点权各不相同。
对于一个a,求树上的最大连通块,使得块的点的权值的集合去掉前a大的数字后中位数最大。
形如:
8
,
4
,
2
,
5
,
3
,
1
(
a
=
3
)
8,4,2,5,3,1 (a=3)
8,4,2,5,3,1(a=3) 则变成
1
,
2
,
3
1,2,3
1,2,3 中位数为
2
2
2。
求
a
∈
[
0
,
n
−
1
]
a \in [0,n-1]
a∈[0,n−1] 的答案。
20pts
直接暴力枚举连通块的点集,没什么好说的。
60pts
我们先钦定 g[i] 代表这个点跟中位数的大小关系(大于中位数为1,小于为-1 , 本身为0)。
形如:序列
8
,
4
,
2
,
5
,
3
,
6
,
7
8,4,2,5,3,6,7
8,4,2,5,3,6,7 钦定中位数为
4
4
4 则原序列的 g 为
1
,
0
,
−
1
,
1
,
−
1
,
1
,
1
1,0,-1,1,-1,1,1
1,0,−1,1,−1,1,1
设 f = 求和g;
对于一个序列 k 意义是删掉最大的前 f 个数,钦定的数就会是中位数。
我们把序列搬到树上,如果钦定他的根为中位数,他的求和g最大的连通块 求和g为f 则 a∈[ 0 , f ] 时 他的根都可以作为中位数。
我们考虑的的 f 最大的连通块的叶子节点一定为1
因为如果有
g
=
−
1
g = -1
g=−1 的叶子则不选这个叶子才是最大的。
则去掉一个为
g
=
1
g = 1
g=1 的叶子就可以得到 求和g 为 f - 1 的连通块。
即我们确定一个根且根为中位数,求出最大的 f 后就可以把答案序列
[
0
,
f
]
[0 , f]
[0,f] 位置的答案跟当前的中位数取
max
\max
max。
所以我们,钦定中位数(根)后,只需要找到最大的 f。
我们考虑如何求 f(f 定义为确定中位数后最大 求和g)
因为是完全二叉树,我们设一个点为
i
i
i,则他的左孩子为
i
×
2
i\times2
i×2,右孩子为
i
×
2
+
1
i\times2 + 1
i×2+1。
首先我们发现,如果我们已经知道了一个点它左右孩子的答案(即f[
i
×
2
i\times2
i×2]和f[
i
×
2
+
1
i\times2 + 1
i×2+1]),我们就可以求出它的答案。
所以我们可以从叶子开始向上推计算答案,这种问题的求解可以使用树形DP。
显然对于一个点的每一个孩子都是两种情况:选或不选。如果选,则这个孩子的贡献为
f
[
s
o
n
]
f[son]
f[son],不选则为 0。
所以对于每一个孩子,我们只需要选一种最大的情况转移过来就行了。
最后加上它本身的贡献
g
[
i
]
g[i]
g[i]。
所以我们可以列出最终的DP方程:
f
[
i
]
=
max
(
0
,
f
[
i
×
2
]
)
+
max
(
0
,
f
[
i
×
2
+
1
]
)
+
g
[
i
]
f[i] = \max(0 , f[i \times 2]) + \max(0 , f[i \times 2 + 1]) + g[i]
f[i]=max(0,f[i×2])+max(0,f[i×2+1])+g[i] ;
我们钦定每一个点为根且为中位数,从叶子开始往上推得,求出最大的f后就可以把答案序列
[
0
,
f
]
[ 0 , f ]
[0,f]位置的答案跟当前的中位数取$ \max $。
复杂度
O
(
n
2
)
O(n^2)
O(n2) ,期望得分 60。
100pts
我认为这个做法更容易理解,但是代码的实现会复杂一些。
n
2
n^2
n2的做法是钦定每一个点为根且为中位数。考虑如何优化。
如果考虑改变钦定根的顺序,
考虑按照
w
w
w从大到小的顺序排序。
考虑每一次换根时候的影响,
当我们按照w从大到小的顺序排序后,每次换根只需要把原来根的位置的给 g 改成 1,新的根的g改成0。
而在树上的影响的(由状态和转移可知,证明很简单在此不做证明,思路为模拟每个点会被哪些点影响)是且仅仅是新的根与就的根之间路径上点的 f。
所以在每次换根的时候只需要把两个根路径重新推一次。
由于是完全二叉树所以深度为
l
o
g
n
logn
logn,所以每一次换根的复杂度是
O
(
l
o
g
n
)
O(logn)
O(logn),总体复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
Code
最后挂个Code [Link],自己感觉还是写的比较思路清晰的。