后缀自动机
时间:2021-07-31
本文章向大家介绍后缀自动机,主要包括后缀自动机使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
后缀自动机
水题清单
例题选记
一 P3804 【模板】后缀自动机 (SAM)
题意:
请你求出 S 的所有出现次数不为 1 的子串的出现次数乘上该子串长度的最大值。
做法:
把每次插入字符新建的节点时记为一,之后在parent树上将儿子的节点值累加到父亲上,该处的节点值即为此节点上所有字符串的出现次数,即可计算求出答案。
原理:
parent树上节点的祖先即为该节点后缀,但假如一个新字符时,即为该前缀的所有后缀的出现次数加 1,即让该节点上parent树上的所有祖先出现次数加 1.
二 P2408 不同子串个数
题意:
求本质不同子串个数。
做法:
枚举每个节点,该节点的 len 减去其父亲的 len 即为该节点代表的字符串的个数,累加求和即可。
三 SP7258 SUBLEX - Lexicographical Substring Search
题意:
求本质不同排名第k小的子串。
做法:
在建立出的后缀自动机的tire树上操作即可。
四 SP1811 LCS - Longest Common Substring
题意:
求2 个字符串的最长公共子串。
做法:
类似于KMP,在每次匹配失败时向上跳父亲,即为找其后缀,每一次跳完后比较答案。
五 P4248 [AHOI2013]差异
题意:
给定一个字符串,
求:
1⩽i<j⩽n∑len(Ti)+len(Tj)−2×lcp(Ti,Tj)
lcp(a,b)表示字符串 a 和字符串 b 的最长公共前缀。
做法:
前两个一起算,lcp单独算。
将字符串翻转,即变为求每两个前缀的最长公共后缀。
任意两个前缀的最长后缀就在其 parent 树的 lca 上,因此在 parent 树上枚举此节点为多少节点的 lca 即可。记pt数组表示此节点是否表示前缀,siz为此子树上有多少个前缀。
六 [SDOI2016]生成魔咒
题意:
每插入一个字符时,当前本质不同的子串个数。
做法:
每插入一个字符,将其他节点向其连边时,将ans加上此节点代表子串数。
在字符类型过多时,在结构体里使用 map 存边。
原文地址:https://www.cnblogs.com/ezuyz/p/15085247.html
- 干货|Kotlin入门第一课:从对比Java开始
- Spark详解04Shuffle 过程Shuffle 过程
- Spark详解02Job 逻辑执行图Job 逻辑执行图
- Spark详解01概览|Spark部署|执行原理概览Job 例子
- Spark详解05架构Architecture架构
- SQL Server常用命令(平时不用别忘了)
- Spark详解06容错机制Cache 和 Checkpoint Cache 和 Checkpoint
- SQL Server 学习笔记
- Collaborative Filtering(协同过滤)算法详解
- 【Hadoop】三句话告诉你 mapreduce 中MAP进程的数量怎么控制?
- Spark系列课程-00xxSpark RDD持久化
- RDD持久化
- P02_Hadoop CDH 5.3.6集群搭建
- P01_Spark开发测试运行环境安装Spark开发测试运行环境安装
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Django 实现文件上传下载API
- 【原创】Spring Boot 如何手写stater
- 【原创】Spring Boot 过滤器、监听器、拦截器的使用
- 关于useState的一切
- 关于useEffect的一切
- (25)Bash数值运算与运算符
- (27)正则表达式
- (28)字符截取命令cut、printf
- (29)字符截取命令awk
- RTSP协议视频平台EasyNVR流媒体服务器音频播放完毕后,视频为什么也会卡住?
- Redis | Redis 有序集合相关命令
- TypeScript 4.0正式发布!现在是开始使用它的最佳时机
- 微服务开源框架TARS 之 基础组件
- Gitlab-ci:从零开始的前端自动化部署
- 从 1 到 0 构建博客项目(导读)