洛谷P4770 [NOI2018]你的名字 [SAM,线段树合并]

传送门


思路

按照套路,直接上后缀自动机。

部分分:\(l=1,r=|S|\)

首先把\(S\)\(T\)的后缀自动机都建出来。

考虑枚举\(T\)中的右端点\(r\),查询以\(r\)结尾的串最长可以往左延伸多长,使得它仍然是\(S\)的子串。记该长度为\(lim_r\)

\(lim_r\)可以在\(SAM_S\)中瞎跳跳出来。

那么答案即为
\[ \sum_{i=2}^{cnt} \max(0,len_i-\max(len_{fa_i},lim_{pos_i})) \]
其中\(i\)\(SAM_T\)的节点,\(len\)就是\(SAM\)中的\(len\)\(fa\)表示parent树上的父亲,\(pos\)表示\(endpos_i\)中的任意一个元素(应该选哪个都一样)。

这个式子的意义就是最长长度经过减去被统计过的后缀(\(len_{fa_i}\))和不合法的部分(\(lim_{pos_i}​\))。

全部:\(l,r\)任意

答案的式子仍是一样,只是\(lim_r\)的求法发生了改变。

由于\([l,r]\)不再包括整一个\(S\),所以在\(SAM_S\)上跳时要保证跳完仍在\(S(l,r)\)中出现过。

这个可以用线段树合并维护\(endpos\)集合得到。

那么就做完了。


代码

由于作业没做完,下午就要返校,所以又咕咕咕了。

猜你喜欢

转载自www.cnblogs.com/p-b-p-b/p/10704233.html