对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案

注意在一个点更新后它的祖先也会被更新,需要最后按拓扑序向上更新一边

其实二分+hash就行

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=10005;
int n,m,ch[N][26],fa[N],tot=1,cur=1,la,dis[N],sa[N],wsu[N],l[N],mn[N],ans;
char s[N];
void ins(int c,int id)
{
la=cur,dis[cur=++tot]=id;
int p=la;
for(;p&&!ch[p][c];p=fa[p])
ch[p][c]=cur;
if(!p)
fa[cur]=1;
else
{
int q=ch[p][c];
if(dis[q]==dis[p]+1)
fa[cur]=q;
else
{
int nq=++tot;
dis[nq]=dis[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[q]=fa[cur]=nq;
for(;ch[p][c]==q;p=fa[p])
ch[p][c]=nq;
}
}
}
void wk()
{
scanf("%s",s+1);
memset(l,0,sizeof(l));
int n=strlen(s+1),nw=1;
for(int i=1,len=1;i<=n;i++)
{
while(nw&&!ch[nw][s[i]-'a'])
nw=fa[nw];
if(!nw)
nw=1,len=0;
else
len=min(len,dis[nw])+1,nw=ch[nw][s[i]-'a'];//cerr<<len<<endl;
l[nw]=max(l[nw],len);
}
for(int i=tot;i>=2;i--)
l[fa[sa[i]]]=max(l[fa[sa[i]]],min(dis[fa[sa[i]]],l[sa[i]]));
// for(int i=2;i<=tot;i++)
// cerr<<l[i]<<" ";cerr<<endl;
for(int i=2;i<=tot;i++)
mn[i]=min(mn[i],l[i]);//,cerr<<mn[i]<<" ";cerr<<endl;
}
int main()
{
scanf("%d%s",&n,s+1);
m=strlen(s+1);
if(n==1)
{
printf("%d\n",m);
return 0;
}
for(int i=1;i<=m;i++)
ins(s[i]-'a',i);
for(int i=2;i<=tot;i++)
wsu[dis[i]]++;
for(int i=1;i<=m;i++)
wsu[i]+=wsu[i-1];
for(int i=m;i>=1;i--)
sa[wsu[dis[i]]--]=i;
for(int i=2;i<=tot;i++)
mn[i]=dis[i];//,cerr<<mn[i]<<" ";cerr<<endl;
for(int i=2;i<=n;i++)
wk();
for(int i=2;i<=tot;i++)
ans=max(ans,mn[i]);
printf("%d\n",ans);
return 0;
}

bzoj 2946: [Poi2000]公共串【SAM】的更多相关文章

  1. BZOJ 2946: [Poi2000]公共串

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 342[Submit][Status][D ...

  2. BZOJ 2946: [Poi2000]公共串( 后缀自动机 )

    一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...

  3. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

  4. bzoj 2946 [Poi2000]公共串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...

  5. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  6. BZOJ 2946 [Poi2000]公共串 ——后缀自动机

    任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...

  7. 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1063  Solved: 469 Description      ...

  8. 【BZOJ】2946: [Poi2000]公共串

    http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意:给n个串,求最大公共子串.(1<=n<=5,每个串长度<=2000) ...

  9. 【bzoj2946】[Poi2000]公共串 后缀自动机

    [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1386  Solved: 620[Submit][Status][Discus ...

随机推荐

  1. eclipse使用正则表达式查找文件内容

    今天有个需求,查找工程中包含汉字的所有文件,随即想到利用eclipse的search功能配合正则表达式. 在eclipse中Ctrl+H,然后在Containing text中输入[\u4e00-\u ...

  2. PHP通用分页

    php通用分页,先看下样式 代码如下: <style> body { font-size:12px;font-family:verdana;width:100%; } div.page{ ...

  3. wyh2000 and pupil

    wyh2000 and pupil  Accepts: 93  Submissions: 925  Time Limit: 3000/1500 MS (Java/Others)  Memory Lim ...

  4. onedrive实现excel在线编辑 online excel

    1.首先用火狐浏览器或者谷歌浏览器登录 https://onedrive.live.com 2.注冊邮箱账户信息 3.在邮箱激活账户信息 4.登录进去.点击我的账户,点击左側文件树.点选上载,将文件上 ...

  5. iOS提交应用至App Store流程及真机调试 一,证书、配置文件

    前言:你要有苹果开发人员账号,我用的是个人账号.其次xcode为xcode 7,因为xcode 7须要 os x 系统 10.11 或更高的版本号, 所以os x 系统也须要 10.11 或更高的版本 ...

  6. linux输入子系统(5) - 学习框架

    注:本系列转自: http://www.ourunix.org/post/290.html input子系统学习系列文章,是我在实际开发过程中遇到也是必须啃下去的第一个Linux驱动,所以有必要记载下 ...

  7. Design Pattern 设计模式1 - Strategy 1

    实现 : Defferent Heros attack Defferently. - 不同的英雄使用不用的招数 Strategy设计的思路: 基类A.更加小的基类B,新的继承类C: 1 从基类A中抽出 ...

  8. React Native安装

    1.安装 1.1 安装Node.js 下载安装即可 1.2 安装Homebrew 终端中执行: $ /usr/bin/ruby -e "$(curl -fsSL https://raw.gi ...

  9. ADO直接调用ACESS数据库MDB

    1.ADO用ODBC链接不会出现堆栈溢出. 2.直接用ADO链接,因为对象不是NEW出来的,导致其成员变量也是栈上的,数组申请过大,栈溢出. 用VECTOR或者NEW对象,应该能解决.

  10. 使用Mock.js进行独立于后端的前端开发

    Mockjs能做什么? 基于 数据模板 生成模拟数据. 基于 HTML模板 生成模拟数据. 拦截并模拟 ajax 请求. 能解决的问题 开发时,前后端进度不同步,后端还没完成数据输出,前端只好写静态模 ...