热门标签 | 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;
}


推荐阅读
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 火星商店问题:线段树分治与持久化Trie树的应用
    本题涉及编号为1至n的火星商店,每个商店有一个永久商品价值v。操作包括每天在指定商店增加一个新商品,以及查询某段时间内某些商店中所有商品(含永久商品)与给定密码值的最大异或结果。通过线段树分治和持久化Trie树来高效解决此问题。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • Splay Tree 区间操作优化
    本文详细介绍了使用Splay Tree进行区间操作的实现方法,包括插入、删除、修改、翻转和求和等操作。通过这些操作,可以高效地处理动态序列问题,并且代码实现具有一定的挑战性,有助于编程能力的提升。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • python的交互模式怎么输出名文汉字[python常见问题]
    在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>,此时我们可以使用print() ... [详细]
  • 本文探讨了如何在模运算下高效计算组合数C(n, m),并详细介绍了乘法逆元的应用。通过扩展欧几里得算法求解乘法逆元,从而实现除法取余的计算。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
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社区 版权所有