http://www.spoj.com/problems/LCS2/ (题目链接)

题意

  求多个串的最长公共子串

Solution

  对其中一个串构造后缀自动机,然后其它串在上面跑匹配。对于每个串都可以跑出在SAM上的每一个节点的最长公共子串的长度,当然,有些节点虽然匹配时可能没有经过,但是在parent树上它的儿子却被经过了,作为儿子的后缀,那么这些节点显然也是被经过的,所以我们需要用parent树上的儿子节点去更新其父亲节点。完成之后,我们再对全局的匹配长度进行更新(取min)。

  爱神:对于SAM初学,要深刻理解出现次数向父亲传递,接收串数从儿子获取这句话。这里的父亲是parent树上的父亲,儿子是SAM图上的后继节点。

代码

// spoj LCS2
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
char s[maxn]; namespace SAM {
int Dargen,sz,last,n;
int par[maxn<<1],len[maxn<<1],ch[maxn<<1][26],mat[maxn<<1],f[maxn<<1];
int b[maxn],id[maxn<<1];
void Extend(int c) {
int np=++sz,p=last;last=np;
len[np]=len[p]+1;
for (;p && !ch[p][c];p=par[p]) ch[p][c]=np;
if (!p) par[np]=Dargen;
else {
int q=ch[p][c];
if (len[q]==len[p]+1) par[np]=q;
else {
int nq=++sz;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
par[nq]=par[q];
par[np]=par[q]=nq;
for (;p && ch[p][c]==q;p=par[p]) ch[p][c]=nq;
}
}
}
void build() {
last=sz=Dargen=1;
n=strlen(s+1);
for (int i=1;i<=n;i++) Extend(s[i]-'a');
}
void pre() {
for (int i=1;i<=sz;i++) b[len[i]]++;
for (int i=1;i<=n;i++) b[i]+=b[i-1];
for (int i=1;i<=sz;i++) id[b[len[i]]--]=i;
for (int i=1;i<=sz;i++) mat[i]=inf;
}
void match() {
int n=strlen(s+1);
int ll=0;
for (int i=1;i<=sz;i++) f[i]=0;
for (int p=Dargen,i=1;i<=n;i++) {
while (p>1 && !ch[p][s[i]-'a']) p=par[p],ll=len[p];
if (ch[p][s[i]-'a']) {
p=ch[p][s[i]-'a'];
f[p]=max(f[p],++ll);
}
}
for (int i=sz;i>=1;i--)
if (f[id[i]]) f[par[id[i]]]=len[par[id[i]]];
for (int i=1;i<=sz;i++) mat[i]=min(mat[i],f[i]);
}
int query() {
int ans=0;
for (int i=1;i<=sz;i++) ans=max(ans,mat[i]);
return ans;
}
}
using namespace SAM; int main() {
scanf("%s",s+1);
build();
pre();
while (scanf("%s",s+1)!=EOF) match();
printf("%d",query());
return 0;
}

【spoj LCS2】 Longest Common Substring II的更多相关文章

  1. 【SPOJ - LCS2】Longest Common Substring II【SAM】

    题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...

  2. 【SPOJ 1812】Longest Common Substring II

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

  3. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  4. 【SPOJ】Longest Common Substring II

    [SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...

  5. 【hdu 1403】Longest Common Substring

    [链接]h在这里写链接 [题意] 求两个串的最长公共子串. [题解] Sa[i]表示的是字典序为i的后缀的起始位置. 可以把两个字符串合在一起(中间用一个比'z'大的字符分割); 则如果Sa[i-1] ...

  6. 【SP1812】LCS2 - Longest Common Substring II

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

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

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

  8. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

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

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

随机推荐

  1. n皇后问题<dfs>

    n皇后问题指的是: n*n的国际象棋棋盘上摆放n个皇后,使其不能互相攻击, 即任意两个皇后都不能处于同一行.同一列或同一斜线上, 问有多少种摆法. 和一般n皇后问题不同的是,现在棋盘上有可能已经放了一 ...

  2. c# mouseenter mousemove区别?

    onmousedown 当用户用任何鼠标按钮单击对象时触发. onmouseenter 当用户将鼠标指针移动到对象内时触发. onmouseleave 当用户将鼠标指针移出对象边界时触发. onmou ...

  3. UITextField和UIViewConteoller

    UITextField控件 UITextFiled常用属性和方法   UITextField是常用的文本输入控件,比如我们用的QQ的登录界面,词典输入要查询的单词都使用了文本框控件,如下图所示.之前介 ...

  4. js浏览器兼容

    //window.event   IE:有window.event对象   FF:没有window.event对象.可以通过给函数的参数传递event对象.如onmousemove=doMouseMo ...

  5. Ubuntu安装pycharm

    在安装pycharm之前,想看一下需要安装那些软件. 在安装前先下载软件 JDK http://www.oracle.com/technetwork/java/javase/downloads/jdk ...

  6. [poj解题]1017

    Packets Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 41014   Accepted: 13776 Descrip ...

  7. createNewFile()与createTempFile()的不同

    1, File 的 createNewFile() 方法:          createNewFile():返回值为 boolean:   方法介绍:当且仅当不存在具有此抽象路径名指定名称的文件时, ...

  8. scp命令和sftp命令

    scp帮助命令: man scpscp功能:下载远程文件或者目录到本地,如果想上传或者想下载目录,最好的办法是采用tar压缩一下,是最明智的选择.从远程主机下载东西到本地电脑拷贝文件命令 scp us ...

  9. [Unity Asset]AssetBundle系列——游戏资源打包

    转载:http://www.cnblogs.com/sifenkesi/p/3557231.html 将本地资源打包,然后放到资源服务器上供游戏客户端下载或更新.服务器上包含以下资源列表:(1)游戏内 ...

  10. mongodb 压缩——3.0+支持zlib和snappy

    转自:https://scalegrid.io/blog/enabling-data-compression-in-mongodb-3-0/ MongoDB 3.0 with the wired ti ...