思路

后缀自动机求多串的最长公共子串

对第一个建出后缀自动机,其他的在SAM上匹配,更新到一个节点的匹配长度最大值即可,最后对所有最大值取min得到一个节点的答案,对所有节点答案求max即可

然后注意,因为parent树上的父节点是是子节点的后缀,所以一旦子节点匹配,也需要更新父节点的最大匹配值(min(maxlen[fa],max(mx[son],mx[fa])))

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int maxlen[202000],suflink[202000],barrel[202000],trans[202000][26],Nodecnt,ranks[202000];
int New_state(int _maxlen,int *_trans,int _suflink){
++Nodecnt;
maxlen[Nodecnt]=_maxlen;
if(_trans)
for(int i=0;i<26;i++)
trans[Nodecnt][i]=_trans[i];
suflink[Nodecnt]=_suflink;
return Nodecnt;
}
int add_len(int u,int c){
int z=New_state(maxlen[u]+1,NULL,0);
while(u&&trans[u][c]==0){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
return z;
}
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
suflink[z]=v;
return z;
}
int y=New_state(maxlen[u]+1,trans[v],suflink[v]);
suflink[v]=suflink[z]=y;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
return z;
}
void c_sort(int n,int lim){
memset(barrel,0,sizeof(barrel));
for(int i=1;i<=n;i++)
barrel[maxlen[i]]++;
for(int i=1;i<=lim;i++)
barrel[i]+=barrel[i-1];
for(int i=1;i<=n;i++)
ranks[barrel[maxlen[i]]--]=i;
}
int Ans[202000],mx[202000];
char s[202000];
int main(){
// freopen("test.in","r",stdin);
int cnt=0,last=1;
Nodecnt=1;
int len;
while(~scanf("%s",s+1)){
++cnt;
len=strlen(s+1);
if(cnt==1){
for(int i=1;i<=len;i++)
last=add_len(last,s[i]-'a');
c_sort(Nodecnt,200010);
for(int i=1;i<=Nodecnt;i++)
Ans[i]=maxlen[i];
}
else{
memset(mx,0,sizeof(mx));
int nowp=1,lent=0;
for(int i=1;i<=len;i++){
if(trans[nowp][s[i]-'a']){
lent++;
nowp=trans[nowp][s[i]-'a'];
}
else{
while(nowp&&trans[nowp][s[i]-'a']==0)
nowp=suflink[nowp];
if(!nowp){
nowp=1;
lent=0;
continue;
}
else{
lent=maxlen[nowp]+1;
nowp=trans[nowp][s[i]-'a'];
}
}
mx[nowp]=max(mx[nowp],lent);
}
for(int i=Nodecnt;i>=1;i--){
int t=ranks[i];
mx[suflink[t]]=max(mx[suflink[t]],mx[t]);
}
for(int i=1;i<=Nodecnt;i++)
Ans[i]=min(Ans[i],mx[i]);
}
}
int ans=0;
for(int i=1;i<=Nodecnt;i++)
ans=max(Ans[i],ans);
printf("%d\n",ans);
return 0;
}

SPOJ 1812 LCS2 - Longest Common Substring II的更多相关文章

  1. spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

    spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...

  2. 【刷题】SPOJ 1812 LCS2 - Longest Common Substring II

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  3. SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)

    手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自 ...

  4. 【SPOJ 1812】Longest Common Substring II

    http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...

  5. SPOJ:LCS2 - Longest Common Substring II

    题面 给定一些字符串,求出它们的最长公共子串 输入格式 输入至多 \(10\) 行,每行包含不超过 \(100000\)个的小写字母,表示一个字符串 输出格式 一个数,最长公共子串的长度 若不存在最长 ...

  6. SPOJ LCS2 - Longest Common Substring II

    LCS2 - Longest Common Substring II A string is finite sequence of characters over a non-empty finite ...

  7. SPOJ LCS2 - Longest Common Substring II 后缀自动机 多个串的LCS

    LCS2 - Longest Common Substring II no tags  A string is finite sequence of characters over a non-emp ...

  8. spoj1812 LCS2 - Longest Common Substring II

    地址:http://www.spoj.com/problems/LCS2/ 题面: LCS2 - Longest Common Substring II no tags  A string is fi ...

  9. 【SP1812】LCS2 - Longest Common Substring II

    [SP1812]LCS2 - Longest Common Substring II 题面 洛谷 题解 你首先得会做这题. 然后就其实就很简单了, 你在每一个状态\(i\)打一个标记\(f[i]\)表 ...

随机推荐

  1. 天梯赛练习题L2-006. 树的遍历

    题目链接 已知一棵树的后序遍历顺序和中序遍历顺序,求层次遍历的顺序: 树的四种遍历: 先序遍历:先访问根节点,再访问左子树,最后访问右子树 中序遍历:先访问左子树,再访问根节点,最后访问右子树 后序遍 ...

  2. Windows下MongoDB设置用户、密码

    在默认情况下,mongod是监听在127.0.0.1之上的,任何客户端都可以直接连接27017,且没有认证. 好处是,用户可以即时上手,不用担心被一堆配置弄的心烦意乱. 坏处是,公网服务器搭建Mong ...

  3. Hello greenDAO(SQLite)

    一.配置Gradle Scripts: 1.1.build.gradle(Project:*****) buildscript { repositories { google() jcenter() ...

  4. emqx源码编译

    1  下载  github上下载 2  找台虚拟机,安装编译所需的环境,erlang   make等 3  执行make命令 重点说一下第3步: 主要是make命令报错 解释:执行make命令后,依赖 ...

  5. Nuxt 自动化部署及打包后文件自动上传七牛云

    1.安装七牛云 2.在项目根目录新建 upload.js 3.上传凭证 4.上传配置,详情参考七牛云文档 5.在 package.js中修改项目build完成执行upload文件命令 7. nuxt. ...

  6. Git知识

    git最小化配置: 配置user.name 和 user.email git config --global user.name 'your_name' git config --global use ...

  7. Go 初体验 - 并发与锁.3 - 竞态

    竞态,就是多个协程同时访问临界区,由并发而产生的数据不同步的状态. 这个说的有点low,没办法,我就是这么表达的,官方的请度娘. 先上代码: 输出: 为何不是1000?就是因为竞态,发生竞态后,最终的 ...

  8. PAT (Basic Level) Practice (中文)1022 D进制的A+B

    1022 D进制的A+B 输入两个非负 10 进制整数 A 和 B (≤2^30^−1),输出 A+B 的 D (1<D≤10)进制数. 输入格式: 输入在一行中依次给出 3 个整数 A.B 和 ...

  9. [python 练习] 计算个税

    题目:利用python计算个税 说明:python有序字典的使用 代码: # -*- coding: utf-8 -*- from collections import OrderedDict # 税 ...

  10. IP地址数据库 | 手机号段归属地数据库 | 行政区划省市区数据库

    2019年4月最新版 IP地址数据库 (全球版·国内版·国外版·掩码版·英文版) 全球旗舰版 454267行   国内精华版 244379行 演示  https://www.qqzeng.com/ip ...