找不到题,没有代码 q w q qwq qwq
一、题目
题目描述
有一颗字典树
t
i
r
e
tire
tire,现在每次加入一个叶子,你需要回答这个点到根路径代表的字符串的最长公共前缀后缀是多少,强制在线。
数据范围
节点数,操作数,字符集大小均为
100000
100000
100000以内。
二、解法
最长公共前缀后缀显然是 k m p kmp kmp,但是 k m p kmp kmp的均摊复杂度分析在树上就失效了,我们要用其他方法。
0x01 trans的优化
考虑数组
t
r
a
n
s
[
x
]
[
c
]
trans[x][c]
trans[x][c]表示在
x
x
x后面安放
c
c
c最后会跳到的地方(用来最长公共前缀递推),有下列柿子:
f
a
i
l
[
x
]
=
t
r
a
n
s
[
f
a
i
l
[
f
a
x
]
]
[
s
x
]
fail[x]=trans[fail[fa_x]][s_x]
fail[x]=trans[fail[fax]][sx]所以我们只需要维护出
t
r
a
n
s
trans
trans即可,可以用可持久化线段树,我们的
t
r
a
n
s
trans
trans直接拷贝
f
a
i
l
[
f
a
x
]
fail[fa_x]
fail[fax]的
t
r
a
n
s
trans
trans,由于我们考虑当前就配成功的情况,到
x
x
x是更新
t
r
a
n
s
[
f
a
x
]
[
s
x
]
trans[fa_x][s_x]
trans[fax][sx]为
x
x
x,时间复杂度
O
(
n
log
n
)
O(n\log n)
O(nlogn)。
0x02 fail的改善
考虑改良
f
a
i
l
fail
fail的跳法,由于一个定理长度-最长公共前缀后缀=最小周期
,我们对
f
a
i
l
fail
fail的跳法分类讨论:
- f a i l < n 2 fail<\frac{n}{2} fail<2n,直接跳。
- o t h e r w i s e otherwise otherwise,我们找到最小周期,然后直接找到当前位置在第一个周期的对应位置,由于当前已经失配,所以所有的周期都不用考虑了,我们加速它,直接跳到最小的,继续跳。
容易发现上述操作都会至少让处理的长度少一半,所以时间复杂度就是 O ( n log n ) O(n\log n) O(nlogn)。
还是没有代码,以后填坑吧