云集训D2T2口胡题解
云集训可海星
题意
我们定义一个括号序列的最大划分为:将一个括号序列划分为最多个合法的连续括号子序列时,子序列个数,例如()()(())的最大划分为3,即()、()、()。特别的,如果它本来就不合法,则为0.一棵树,每个节点有一个)或(,对于一条路径有一个括号序列,需要求出最大划分为k的路径有多少条。N1e5。
做法
显然一眼点分啊。
然后考虑怎么做。
引理1
一条路径合法,当且仅当在任意一个节点划分都能划分成类似()(())(((和)))()()()((()))的形式,要求两端后缀和相同,且在后缀之外自身合法,并且其最大划分数等于两端后缀和为0的位置之和,若中间不为0的话加一。
举个栗子:
( ( ( ) ( ) ( ) ) ) ( ) ( ( ) ) ( (
1 2 3 2 3 2 3 2 1 0 1 0 1 2 1 0 1 2
那么在前方三处0是一定可以划分的,我们定义它的划分数cnt为3,并且定义这个串的极差为2(即结尾处的后缀和)。
那么它能和所有极差为-2的串拼成一个完整的串。
对于每个极值而言,一个cnt为a的前缀和cnt为b的后缀拼成的串的cnt为a+b(若极值不为0还要+1),这个东西是个卷积的形式。
那么我们对于每个极值分别fft,对于每个极值而言,做fft的代价就是cnt之和的log。
考虑这样会导致算重
例如(()()会自己匹配自己
(()()+)(自己的后缀)=(()())合法,但是事实上不合法。
我们就对于每个子树再做一次fft以删去自己和自己匹配的贡献。
复杂度证明
引理1
一旦极值改变,cnt必然归0.
例如
( ( ( ) ( ) ( ) ) ) ( ) ( ( ) ) ( (
1 2 3 2 3 2 3 2 1 0 1 0 1 2 1 0 1 2
在前面添加(后cnt瞬间跌落为0。
所以任何一个cnt的增加必然是由两个节点唯一贡献的,cnt之和不超过
所
有
节
点
2
\frac{所有节点}{2}
2所有节点。
fft会造成
s
i
z
e
子
树
∗
l
o
g
(
s
i
z
e
子
树
)
size子树*log(size子树)
size子树∗log(size子树)的贡献,严格小于
s
i
z
e
当
前
联
通
快
∗
l
o
g
(
s
i
z
e
当
前
联
通
块
)
size当前联通快*log(size当前联通块)
size当前联通快∗log(size当前联通块),即总复杂度为
n
l
o
g
2
(
n
)
nlog^2(n)
nlog2(n)。