对于本题这样的多字符串的子串匹配问题,其实用广义后缀自动机就可以很好的解决,感觉会比普通的后缀自动机做法方便一些。

首先记录出每个节点被多少个字符串更新,也就是记录每个节点有多少个字符串能到达它,可以通过在\(Parent\)树上求子树和处理出。

若所有字符串都能到达一个节点,也就是该节点所对应的串为所有字符串的子串,那么该节点是一个合法的转移状态。

那么就可以直接拿这些字符串中的任意一个字符串在自动机上匹配,就像LCS - Longest Common Substring一样,只向合法状态转移,记录当前匹配出的最长公共子串的最大长度即可。

实现细节看代码吧。

\(code:\)

#include<bits/stdc++.h>
#define maxn 2000010
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,las,tot=1,root=1,num,ans;
int fa[maxn],len[maxn],ch[maxn][30],siz[maxn][12];
char s[maxn];
struct edge
{
int to,nxt;
}e[maxn];
int head[maxn],edge_cnt;
void add(int from,int to)
{
e[++edge_cnt]=(edge){to,head[from]};
head[from]=edge_cnt;
}
void insert(int c,int id)
{
int p=las,np=las=++tot;
len[np]=len[p]+1,siz[np][id]++;
while(p&&!ch[p][c]) ch[p][c]=np,p=fa[p];
if(!p) fa[np]=root;
else
{
int q=ch[p][c];
if(len[q]==len[p]+1) fa[np]=q;
else
{
int nq=++tot;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
len[nq]=len[p]+1,fa[nq]=fa[q],fa[q]=fa[np]=nq;
while(ch[p][c]==q) ch[p][c]=nq,p=fa[p];
}
}
}
void dfs(int x)
{
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
dfs(y);
for(int id=1;id<=num;++id)
siz[x][id]+=siz[y][id];
}
}
bool check(int p)
{
if(!p) return false;
for(int i=1;i<=num;++i)
if(!siz[p][i])
return false;
return true;
}
void work()
{
for(int i=2;i<=tot;++i) add(fa[i],i);
dfs(root);
int p=root,l=0;
for(int i=1;i<=n;++i)
{
int c=s[i]-'a';
if(check(ch[p][c])) l++,p=ch[p][c];
else
{
while(p&&!check(ch[p][c])) p=fa[p];
if(p) l=len[p]+1,p=ch[p][c];
else l=0,p=root;
}
ans=max(ans,l);
}
}
int main()
{
while(scanf("%s",s+1)!=EOF)
{
n=strlen(s+1),las=root,num++;
for(int i=1;i<=n;++i) insert(s[i]-'a',num);
}
work(),printf("%d\n",ans);
return 0;
}

题解 SP1812 【LCS2 - Longest Common Substring II 】的更多相关文章

  1. SP1812 LCS2 - Longest Common Substring II

    能匹配上子串的节点对它的所有parent都有贡献 在树上转移即可 #include<cstdio> #include<algorithm> #include<cstrin ...

  2. 【SP1812】LCS2 - Longest Common Substring II

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

  3. 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 ...

  4. SPOJ LCS2 - Longest Common Substring II

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

  5. spoj1812 LCS2 - Longest Common Substring II

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

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

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

  7. SPOJ1812 LCS2 - Longest Common Substring II【SAM LCS】

    LCS2 - Longest Common Substring II 多个字符串找最长公共子串 以其中一个串建\(SAM\),然后用其他串一个个去匹配,每次的匹配方式和两个串找\(LCS\)一样,就是 ...

  8. LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  9. 【刷题】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 ...

随机推荐

  1. netty--helloword程序

    1.使用netty需要使用到下面的java包 netty-all-5.0.0.Alpha2.jar 我们来看下面具体的代码 1. 创建一个ServerBootstrap实例 2. 创建一个EventL ...

  2. java中整数的常量优化机制

    java正常两个整数类型相加默认提升为int类型,如接受的类型比int小则会报错,当两个整数常量相加不超范围的情况下是不会报错 byte b = 3 +4: 条件:等号的右边必须全部都是整数常量才可以 ...

  3. Day12-微信小程序实战-交友小程序-优化“附近的人”页面与serach组件的布局和样式以及搜索历史记录和本地缓存*内附代码)

    回顾/:我们已经实现了显示附近的人的功能了,可以多个人看到附近的人页面了 但是还是要进行优化有几个问题:1.我们用户选择了其他的自定义头像之后,在首页可以看到头像的变化,但是在附近的人中头像会变成报错 ...

  4. 计算机网络之DNS常见攻击

    DNS欺骗 在Internet上存在的DNS服务器有绝大多数都是用bind来架设的,使用的bind版本主要为bind 4.9.5+P1以前版本和bind 8.2.2-P5以前版本.这些bind有个共同 ...

  5. 且谈 Apache Spark 的 API 三剑客:RDD、DataFrame 和 Dataset

    作者:Jules S. Damji 译者:足下 本文翻译自 A Tale of Three Apache Spark APIs: RDDs, DataFrames, and Datasets ,翻译已 ...

  6. ES6 promise用法总结

    一   什么时候promise? promise是异步编程的一个解决方案,是一个构造函数,身上带着all,resolve,reject,原型上有cath,then等方法 promise有两个特点: 1 ...

  7. proxool配置连接池

    http://log-cd.iteye.com/blog/199482 1.Hiebernate配置文件中引用proxool配置文件: <hibernate-configuration> ...

  8. 如何针对Thymeleaf模板抽取公共页面

    对于公共页面(导航栏nav.页头head.页尾footer)的抽取有三种方式:        1)基于iframe进行抽取,这种方式很有效,但比较老了,另外为了页面的自适应性,还得做不少工作:     ...

  9. 看源码,重新审视Spring Security中的角色(roles)是怎么回事

    在网上看见不少的博客.技术文章,发现大家对于Spring Security中的角色(roles)存在较大的误解,最大的误解就是没有搞清楚其中角色和权限的差别(好多人在学习Spring Security ...

  10. C++ 自动资源释放的单例模式

    代码思想就是程序结束时会自动释放静态/全局资源时删除单例资源. //.h class CSingleton { public: static CSingleton* Singleton() { ret ...