热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

广义后缀自动机在字符串处理中的应用

本文详细探讨了如何使用广义后缀自动机解决MemSQLStart[c]UP2.0竞赛第一轮E题——Threestrings。通过构建和分析后缀自动机,我们能够高效地统计多个字符串中子串出现的频率。

本文旨在深入解析广义后缀自动机(Generalized Suffix Automaton, GSA)在字符串处理问题中的应用,特别是在MemSQL Start[c]UP 2.0竞赛第一轮E题——Three strings中的具体实现。通过本题,我们可以学习到如何利用GSA来高效解决多字符串的子串匹配与计数问题。


问题描述:给定三个字符串,任务是计算每个可能长度的子串在这三个字符串中同时出现的次数,并输出这些计数结果。


#include
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair
#define PLI pair
#define ull unsigned long long
using namespace std;
const int N = 5e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
int n, ans[N], len[3];
char s[3][N];
struct SuffixAutomaton {
int cur, cnt, ch[N<<1][26], id[N<<1], fa[N<<1], dis[N<<1], sz[N<<1], c[N];
int num[3][N<<1];
SuffixAutomaton() : cur(1), cnt(1) {}
void init() {
for(int i = 1; i <= cnt; i++) {
memset(ch[i], 0, sizeof(ch[i]));
sz[i] = c[i] = dis[i] = fa[i] = 0;
}
cur = cnt = 1;
}
int extend(int p, int c) {
cur = ++cnt; dis[cur] = dis[p] + 1;
while(p && !ch[p][c]) ch[p][c] = cur, p = fa[p];
if(!p) fa[cur] = 1;
else {
int q = ch[p][c];
if(dis[q] == dis[p] + 1) fa[cur] = q;
else {
int nt = ++cnt; dis[nt] = dis[p] + 1;
memcpy(ch[nt], ch[q], sizeof(ch[q]));
fa[nt] = fa[q]; fa[q] = fa[cur] = nt;
while(ch[p][c] == q) ch[p][c] = nt, p = fa[p];
}
}
sz[cur] = 1;
return cur;
}
void topo(int n) {
for(int i = 1; i <= cnt; i++) c[dis[i]]++;
for(int i = 1; i <= n; i++) c[i] += c[i-1];
for(int i = cnt; i >= 1; i--) id[c[dis[i]]--] = i;
}
void solve() {
for(int i = 0; i <3; i++) {
scanf("%s", s[i]); len[i] = strlen(s[i]);
for(int j = 0, last = 1; j last = extend(last, s[i][j] - 'a');
}
for(int i = 0; i <3; i++) {
for(int j = 0, p = 1; j p = ch[p][s[i][j] - 'a'];
num[i][p]++;
}
}
topo(max(len[0], max(len[1], len[2])));
for(int i = cnt; i >= 1; i--)
for(int j = 0; j <3; j++)
num[j][fa[id[i]]] += num[j][id[i]];
for(int i = 2; i <= cnt; i++) {
int ret = 1ll * num[0][i] * num[1][i] % mod * num[2][i] % mod;
int mx = dis[i], mn = dis[fa[i]] + 1;
ans[mn] = (ans[mn] + ret) % mod;
ans[mx + 1] = (ans[mx + 1] - ret + mod) % mod;
}
int Len = min(len[0], min(len[1], len[2]));
for(int i = 1; i <= Len; i++) {
ans[i] = (ans[i] + ans[i-1]) % mod;
printf("%d ", ans[i]);
}
puts("");
}
} sam;
int main() {
sam.solve();
return 0;
}


推荐阅读
  • 深入解析Android中的SQLite数据库使用
    本文详细介绍了如何在Android应用中使用SQLite数据库进行数据存储。通过自定义类继承SQLiteOpenHelper,实现数据库的创建与版本管理,并提供了具体的学生信息管理示例代码。 ... [详细]
  • 设有10个取值范围为0~9的互不相等的整数存放在数组A[10]中,要求将它们从小到大排序,并存放在一个新数组B[10]中(数据结构;Language:C)
    编程思想:将A的整数按其取值直接放入B的相应位置即可实现A中整数从小到大的排列。代码:#include包含scanf_s()和pri ... [详细]
  • MySQL锁机制详解
    本文深入探讨了MySQL中的锁机制,包括表级锁、行级锁以及元数据锁,通过实例详细解释了各种锁的工作原理及其应用场景。同时,文章还介绍了如何通过锁来优化数据库性能,避免常见的并发问题。 ... [详细]
  • 本文探讨了在QT框架中如何有效遍历文件内容,并解决了一个常见的错误,即文件内容读取为空时弹窗无法正常显示的问题。 ... [详细]
  • ▶书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall算法可能含负环的有边权有向图任意两点之间的最短路径●有边权有向图的邻接矩阵1 ... [详细]
  • 本文详细介绍了Java集合框架中的Collection体系,包括集合的基本概念及其与数组的区别。同时,深入探讨了Comparable和Comparator接口的区别,并分析了各种集合类的底层数据结构。最后,提供了如何根据需求选择合适的集合类的指导。 ... [详细]
  • 探讨在使用Rails框架创建数据库记录时,created_at字段未能正确反映系统当前时间的原因及解决方法。 ... [详细]
  • 华硕主板BIOS更新指南(图文)
    本文详细介绍了如何安全有效地更新华硕主板的BIOS,包括准备工作、具体步骤以及注意事项。BIOS是计算机基本输入输出系统的关键组成部分,负责初始化硬件并加载操作系统,定期更新BIOS可以增强系统的稳定性和兼容性。 ... [详细]
  • 初探Java编程:从入门到实践
    本文旨在为初学者提供Java编程的基础知识,涵盖程序、算法、流程图的概念,以及JDK环境的配置和Eclipse的使用方法。 ... [详细]
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • BUUCTF [ZJCTF 2019] NiZhuanSiWei 解题报告
    本文详细解析了BUUCTF [ZJCTF 2019] NiZhuanSiWei的解题过程,包括代码审计、PHP伪协议的使用以及反序列化漏洞的利用。 ... [详细]
  • C语言实现推箱子游戏的完整代码
    本文详细介绍了如何使用C语言在Linux环境下实现一个简单的推箱子游戏,包括游戏的基本规则、地图设计及代码实现。适合C语言初学者学习。 ... [详细]
  • 本文详细介绍了如何正确安装Java EE SDK,并解决在安装过程中可能遇到的问题,特别是关于servlet代码在Apache Tomcat 10中无法运行的情况。 ... [详细]
  • 本文深入探讨了JavaScript中实现继承的四种常见方法,包括原型链继承、构造函数继承、组合继承和寄生组合继承。对于正在学习或从事Web前端开发的技术人员来说,理解这些继承模式对于提高代码质量和维护性至关重要。 ... [详细]
  • 在Linux系统上构建Web服务器的详细步骤
    本文详细介绍了如何在Linux系统上搭建Web服务器的过程,包括安装Apache、PHP和MySQL等关键组件,以及遇到的一些常见问题及其解决方案。 ... [详细]
author-avatar
花落酒未醉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有