bzoj 2946 [Poi2000]公共串——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946
对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走到哪些点了;只要有一个自动机上走不下去了,就都走不下去了。每走到一个新地方就更新一下 ans 。
或者像网上的其他题解一样,对一个串建一个后缀自动机,其他串跑一遍并在 parent 树上更新了之后得知自动机的每个点在当前串上能匹配的长度,最后对自动机上每个点的答案取 max 。不过没写这个。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=N<<,K=,tN=;
char s[N]; int T,lst,cnt,go[tN][M][K],fa[tN][M],l[tN][M],p[M][tN],ans;
int Mx(int a,int b){return a>b?a:b;}
void add(int x,int w)
{
int p=lst,np=++cnt;lst=np;l[x][np]=l[x][p]+;
for(;p&&!go[x][p][w];p=fa[x][p])go[x][p][w]=np;
if(!p)fa[x][np]=;
else
{
int q=go[x][p][w];
if(l[x][q]==l[x][p]+)fa[x][np]=q;
else
{
int nq=++cnt;l[x][nq]=l[x][p]+;
fa[x][nq]=fa[x][q];fa[x][q]=nq;fa[x][np]=nq;
memcpy(go[x][nq],go[x][q],sizeof go[x][q]);
for(;go[x][p][w]==q;p=fa[x][p])go[x][p][w]=nq;
}
}
}
void dfs(int cr,int len)
{
ans=Mx(ans,len);//
for(int w=;w<=;w++)
if(go[][cr][w])
{
bool flag=; int d=go[][cr][w];
for(int t=;t<=T;t++)
if(!go[t][p[cr][t]][w]){flag=;break;}
else p[d][t]=go[t][p[cr][t]][w];
if(!flag)continue;
dfs(d,len+);
}
}
int main()
{
scanf("%d",&T);
for(int t=;t<=T;t++)
{
scanf("%s",s);int d=strlen(s);
lst=cnt=;
for(int i=;i<d;i++)add(t,s[i]-'a'+);
}
for(int t=;t<=T;t++)p[][t]=;
dfs(,); printf("%d\n",ans);
return ;
}
bzoj 2946 [Poi2000]公共串——后缀自动机的更多相关文章
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- BZOJ 2946 [Poi2000]公共串 ——后缀自动机
任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...
- BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)
题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- 【bzoj2946】[Poi2000]公共串 后缀自动机
[Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1386 Solved: 620[Submit][Status][Discus ...
- BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)
求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...
- BZOJ2946 [Poi2000]公共串(后缀自动机)
Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输 ...
- bzoj 2946: [Poi2000]公共串【SAM】
对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...
- 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1063 Solved: 469 Description ...
随机推荐
- Linux系统下wget命令的使用教程
一.Linux wget简介 wget是linux上的命令行的下载工具.这是一个GPL许可证下的自由软件.Linux wget支持HTTP和FTP协议,支持代理服务器和断点续传功能,能够自动递归远程主 ...
- 深入Jetty源码之Servlet框架及实现(Servlet、Filter、Registration)
概述 Servlet是Server Applet的缩写,即在服务器端运行的小程序,而Servlet框架则是对HTTP服务器(Servlet Container)和用户小程序中间层的标准化和抽象.这一层 ...
- [javascript]JS如何获取当前时间戳
[javascript]JS如何获取当前时间戳 一.总结 一句话总结:var timestamp = Date.parse(new Date()); 结果是带三位毫秒的,再除个1000取整即可 1.j ...
- 处理跨线程操作问题(使用Action和delegate或lambda表达式)
方法A: Action f = () => { txtProcess.Text = "开始更新程序.. ...
- jQuery: Redirect to other URL
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> ...
- poj2723 2-sat
当两个门锁相同时,这个钥匙必须用,不同时分开用 可以直接遍历门,当然二分更快 #include<map> #include<set> #include<cmath> ...
- Java多线程编程总结
Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调 ...
- org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML.
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Offic ...
- 【scala】Option类型
一般来说,对于每种语言都会有一个关键字来表示一个对象引用的“无”.在Java中使用的是null. 而Scala则融合了函数式编程的风格,当预计到变量或者函数返回值可能不会引用任何值的时候,使用Opti ...
- opencv:图像的腐蚀和膨胀
1.图像的腐蚀 图像的腐蚀和膨胀都是相对于像素值高(白色方向)说的,腐蚀简单的说就是白色”被腐蚀“了,也就是像素值低(黑色方向)的变多,白色变少. 腐蚀的原理是利用一个内核对图像进行卷积(扫描),内核 ...