【spoj LCS2】 Longest Common Substring II
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的更多相关文章
- 【SPOJ - LCS2】Longest Common Substring II【SAM】
题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...
- 【SPOJ 1812】Longest Common Substring II
http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...
- 【SPOJ】Longest Common Substring II (后缀自动机)
[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...
- 【SPOJ】Longest Common Substring II
[SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...
- 【hdu 1403】Longest Common Substring
[链接]h在这里写链接 [题意] 求两个串的最长公共子串. [题解] Sa[i]表示的是字典序为i的后缀的起始位置. 可以把两个字符串合在一起(中间用一个比'z'大的字符分割); 则如果Sa[i-1] ...
- 【SP1812】LCS2 - Longest Common Substring II
[SP1812]LCS2 - Longest Common Substring II 题面 洛谷 题解 你首先得会做这题. 然后就其实就很简单了, 你在每一个状态\(i\)打一个标记\(f[i]\)表 ...
- SPOJ1812 LCS2 - Longest Common Substring II【SAM LCS】
LCS2 - Longest Common Substring II 多个字符串找最长公共子串 以其中一个串建\(SAM\),然后用其他串一个个去匹配,每次的匹配方式和两个串找\(LCS\)一样,就是 ...
- 【SPOJ】Longest Common Substring(后缀自动机)
[SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...
- spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)
spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...
随机推荐
- POJ1611 The Suspects 并查集模板题
题目大意:中文题不多说了 题目思路:将每一个可能患病的人纳入同一个集合,然后遍历查找每个点,如果改点点的根节点和0号学生的根节点相同,则该点可能是病人. 模板题并没有思路上的困难,只不过在遍历时需要额 ...
- ZOJ3944People Counting<暴力/枚举>
题意:输入一张照片,给出人物的特征,判断有多少个人. .O. /|\ (.) 思路:按照3*3的图统计,只要有一个点符合就加1 #include<cstdio> #include<i ...
- 块和内嵌总结,以及各个标签的应用。其中的ul ol dl特殊定义为auto,使得里面的内容展开
<!doctype html> <html> <head> <meta charset="UTF-8"/> <title> ...
- js中的全局函数
以前没搞懂JS的全局函数,全局函数和window对象的函数不一样.全局函数不属于任何一个内置对象. JS包含以下7个全局函数,用于一些常用的功能:escape(),eval(),isNan(),isF ...
- AOP 在javascript 中的使用
AOP(Aspect Oriented Programming) 意为面向切面编程 可以在不修改原有代码的情况下增加新功能,利用AOP可以对业务逻辑各个部分进行隔离,从而使得业务逻辑各部分的耦合度降低 ...
- 【HighCharts系列教程】十、图例属性——legend
一.legend属性说明 Legend是HighCharts图表的图例属性,如图 默认情况下,HighCharts都会有图例,无特殊情况,默认即可满足需求,所以一般不用配置Legend属性. 二.la ...
- iOS系统弃用方法更新方法
-boundingRectWithSize:options:attributes:context:用法 - (CGSize)sizeWithFont:(UIFont *)font constraine ...
- Bootstrap的文档大概介绍
1.预置CSS样式 (1)Normalize.css 增强浏览器表现的一致性. (2)布局容器——版芯:container. ①.container 类用于固定宽度并支持响应式布局的容器. ...
- x86_64是什么意思
x86指的是32位计算机的架构,也指32位的操作系统,比如i386,i686,i486等:x86_64和x64指的都是64位架构,也指64位操作系统
- 微信小程序一些简单的快捷键
常用快捷键 格式调整 Ctrl+S:保存文件Ctrl+[, Ctrl+]:代码行缩进Ctrl+Shift+[, Ctrl+Shift+]:折叠打开代码块Ctrl+C Ctrl+V:复制粘贴,如果没有选 ...