惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
博客园 - Franky
The Cloudflare Blog
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
B
Blog
Y
Y Combinator Blog
V
V2EX
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
博客园 - 司徒正美
IT之家
IT之家
G
Google Developers Blog
C
Check Point Blog
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

某岛

AtCoder Beginner Contest 409 Luogu P5325. 【模板】Min_25 筛 UOJ #188. 【UR #13】Sanrd AtCoder Beginner Contest 371 AtCoder Beginner Contest 369 RPGMaker 2k3 百科 OneShot 的考古 2024“开创拓芯”游戏创享节的相关记录 CJ 回来后的戒断反应 Luogu P10221. [省选联考 2024] 重塑时光 Luogu P5308 [COCI2018-2019#4] Akvizna wqs 二分 歌唱王国 Lean 相关 BZOJ 3153. Sone1 The 2023 ICPC World Finals Luxor 新巴别塔 Sora 的想象与思考 Facebook Hacker Cup 2023 Round 1 AtCoder Beginner Contest 322 LLaMA 2 相关 HuggingFace AI Game Jam ACL 2023 Trans 相关… Luogu P2053. [SCOI2007] 修车 Luogu P1973. [NOI2011] NOI 嘉年华 Luogu P1933. [NOI2010] 旅行路线 Luogu P1954. [NOI2010] 航空管制 Luogu P2048. [NOI2010] 超级钢琴 Luogu P2046. [NOI2010] 海拔
UOJ #608. 【UR #20】机器蚤分组
2021-07-12 · via 某岛

题意

https://uoj.ac/problem/608
给定一个字符串 T,每次询问一个子串 T[l,r],返回其最长重复子串的长度。

做法

证明?参考 官方题解
我们来讨论怎么用 SAM 搞子串的重复子串。

首先回忆怎么用 SAM 求最长重复子串。
直接返回 fail 树上非叶子节点的 len[u] 就好。

再考虑怎么求某个前缀 T[1,r] 的最长重复子串。
我们考虑离线,按照 r 端点从小到大排序,
按照顺序每次在 fail 树上找到前缀所对应的叶子节点,
往根节点染色即可。用染色路径上第一个碰到的节点的 len 的长度更新答案。
因为每个节点只会被染色一次,所以暴力染色即可。

最后考虑一般情况 T[l,r],我们显然需要对染色进行区分,
我们希望每个状态越晚被染色越好,因为越晚,它可能对答案的贡献就越长。
我们不妨画一下示意图。。考虑下面的情况。。考虑到时刻 r 的时候经过节点 u。
u 历史上在时点 l1 和 l2 都被染色过,且 len[u] = 4,那么有:
设 l1 < l2 < r。
—l1, —l2, —r
那么我们可以忽略 l1,并且只有在 l <= l2-3 的時候,才能得到
完整的 4 长度的贡献,在 l2 时刻,因为询问的左区间不够长,只有对答案带来 1 的贡献。

具体说来,不妨对每个可能三元组 (l,r,u)。
r 表示当前染色的时点,l 表示历史上这个节点最晚被染色的时点。
u 表示 l, r 到根路径上的某个公共祖先。

我们可以用线段树。。。
支持询问区间最值,
以及区间覆盖,和区间等差数列覆盖两个操作即可。

具体说来就是。。。
checkMax1(1, l-len[u], len[u]),表示对区间 [1, 1-len[u]] 与 len[u] 取 max。
以及
checkMax2(l-len[u]+1, l),表示对 l-len[u]+1, l-len[u]+2,…, l 这个区间分别 checkMax 上 l, l-1, …, 1 这个递减数列。

因为染色过程总是叶子到根节点的路径,所以可以用动态树。
这里的动态树也可以用启发式合并替代。

Posted by xiaodao
Category: 日常