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. dyld: Symbol not found: _OBJC_CLASS_$_UIBlurEffect

    信息如下: 不知道为撒出现这个问题,查资料也木有查到..看提示信息可能是UIKit的问题,所以就试着这样解决,结果居然好了....有谁知道原因的告诉额一声啊,拜托!

  2. PAT (Advanced Level) 1057. Stack (30)

    树状数组+二分. #include<iostream> #include<cstring> #include<cmath> #include<algorith ...

  3. sql server 更新两个表的某个字段

    --临时表 create table tmp_cup ( a varchar(20), b varchar(50), c varchar(20) ) select * from t_customer ...

  4. Linux 互斥锁的实现原理(pthread_mutex_t)

    本文参考--http://www.bitscn.com/os/linux/201608/725217.html 和http://blog.csdn.net/jianchaolv/article/det ...

  5. 原生的ajax(json)

    function getXHR(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else{ try{ return new Ac ...

  6. 转 互联网推送服务原理:长连接+心跳机制(MQTT协议)

    http://blog.csdn.net/zhangzeyuaaa/article/details/39028369 目录(?)[-] 无线移动网络的特点 android系统的推送和IOS的推送有什么 ...

  7. PAT (Advanced Level) 1021. Deepest Root (25)

    先并查集判断连通性,然后暴力每个点作为根节点判即可. #include<iostream> #include<cstring> #include<cmath> #i ...

  8. Vmware克隆虚拟机后网卡eth0变eth1解决

    在克隆虚拟机的过程中,发现新克隆的机器的网卡由eth0变成了eth1,然而并没有eth1的配置文件. 1.#ip a 查看当前ip地址,发现是eth1网卡 2.#ll /etc/sysconfig/n ...

  9. php自学笔记3

    -------补充--------建议定义常量时,判断常量名是否被定义,用defined()判断,返回布尔型if(!defined("POEM")){//没定义过 define(& ...

  10. ajax跨域实现api 接口调用

    背景: 想实现跨域去调用接口, 然后同时支持下次调用,能够带cookie信息过来,同时支持来自多个源头的域名的跨域调用. 1.这样支持来自所有域名的跨域调用: 不支持跨域是,浏览器报错: 在api接口 ...