雅礼集训D2T2

云集训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子树) sizelog(size)的贡献,严格小于 s i z e 当 前 联 通 快 ∗ l o g ( s i z e 当 前 联 通 块 ) size当前联通快*log(size当前联通块) sizelog(size),即总复杂度为 n l o g 2 ( n ) nlog^2(n) nlog2(n)

你可能感兴趣的:(解题报告)