[bzoj十连测]Problem

找不到题,没有代码 q w q qwq

一、题目

题目描述
有一颗字典树 t i r e tire ,现在每次加入一个叶子,你需要回答这个点到根路径代表的字符串的最长公共前缀后缀是多少,强制在线。
数据范围
节点数,操作数,字符集大小均为 100000 100000 以内。

二、解法

最长公共前缀后缀显然是 k m p kmp ,但是 k m p kmp 的均摊复杂度分析在树上就失效了,我们要用其他方法。

0x01 trans的优化

考虑数组 t r a n s [ x ] [ c ] trans[x][c] 表示在 x x 后面安放 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] 所以我们只需要维护出 t r a n s trans 即可,可以用可持久化线段树,我们的 t r a n s trans 直接拷贝 f a i l [ f a x ] fail[fa_x] t r a n s trans ,由于我们考虑当前就配成功的情况,到 x x 是更新 t r a n s [ f a x ] [ s x ] trans[fa_x][s_x] x x ,时间复杂度 O ( n log n ) O(n\log n)

0x02 fail的改善

考虑改良 f a i l fail 的跳法,由于一个定理长度-最长公共前缀后缀=最小周期,我们对 f a i l fail 的跳法分类讨论:

  • f a i l < n 2 fail<\frac{n}{2} ,直接跳。
  • o t h e r w i s e otherwise ,我们找到最小周期,然后直接找到当前位置在第一个周期的对应位置,由于当前已经失配,所以所有的周期都不用考虑了,我们加速它,直接跳到最小的,继续跳。

容易发现上述操作都会至少让处理的长度少一半,所以时间复杂度就是 O ( n log n ) O(n\log n)

还是没有代码,以后填坑吧
发布了217 篇原创文章 · 获赞 12 · 访问量 5155

猜你喜欢

转载自blog.csdn.net/C202044zxy/article/details/104055472