spoj - Longest Common Substring(后缀自动机模板题)
Longest Common Substring
题意
求两个串的最长公共子串。
分析
第一个串建后缀自动机,第二个串在自动机上跑,对于自动机上的结点(状态)而言,它所代表的最大长度为根结点到当前结点的长度,而它的前继结点的串一定是这个结点串的后缀串(或空串)。
匹配过程中一旦失配,自动机上的结点找它的前继结点,继续向后匹配即可。
code
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 250005;
char s[MAXN];
/* 性质:
① 从root到任意结点p的每条路径上的字符组成的字符串,都是当前串t的子串
② 因为满足性质一,所以如果当前结点p是可以接收新后缀的结点,那么从root到任意结点p的每条路径上的字符组成的字符串,都是必定是当前串t的后缀
③ 如果结点p可以接收新的后缀,那么p的fa指向的结点也可以接收后缀,反过来就不行
从 root 出发的任何子串最终都会到达一个合法状态,而非子串最终都会“无路可走”
*/
struct SAM {
int ch[MAXN << 1][26];
int fa[MAXN << 1]; // 前继结点,如果当前结点可以接受某个后缀那么它的前继结点也可以接受
int len[MAXN << 1]; // 从根结点到该结点的最大距离,这个状态(结点)代表的串长度区间 (len[fa], len]
int cnt, last;
void init() {
memset(ch, 0, sizeof ch);
memset(fa, 0, sizeof fa);
last = cnt = 1; // root节点为 1 ,所以添加的字符从 2 开始
}
void add(int c) {
int p = last, np = last = ++cnt;
len[np] = len[p] + 1;
while(!ch[p][c] && p) {
ch[p][c] = np;
p = fa[p];
}
if(p == 0) fa[np] = 1;
else {
int q = ch[p][c];
if(len[p] + 1 == len[q]) { // p、q之间无其他结点
fa[np] = q;
} else { // np的加入导致前面某个结点的状态发生改变
int nq = ++cnt;
len[nq] = len[p] + 1;
memcpy(ch[nq], ch[q], sizeof ch[q]);
fa[nq] = fa[q];
fa[q] = fa[np] = nq;
while(ch[p][c] == q && p) {
ch[p][c] = nq;
p = fa[p];
}
}
}
}
} sam;
int main() {
scanf("%s", s);
int len = strlen(s);
sam.init();
for(int i = 0; i < len; i++) {
sam.add(s[i] - 'a');
}
scanf("%s", s);
len = strlen(s);
int p = 1;
int ans = 0;
int c = 0;
for(int i = 0; i < len; ) {
while(sam.ch[p][s[i] - 'a']) {
p = sam.ch[p][s[i] - 'a'];
i++;
c++;
}
ans = max(ans, c);
if(!c) i++;
else {
p = sam.fa[p];
c = sam.len[p];
}
}
printf("%d\n", ans);
return 0;
}
spoj - Longest Common Substring(后缀自动机模板题)的更多相关文章
- SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- SPOJ1811 LCS - Longest Common Substring(后缀自动机)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- SPOJ 1811 Longest Common Substring 后缀自动机
模板来源:http://www.neroysq.com/?p=76 思路:http://blog.sina.com.cn/s/blog_7812e98601012dfv.html 题意就是求两个字符串 ...
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题
链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...
- 后缀自动机(SAM):SPOJ Longest Common Substring II
Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB A string is finite sequence of ...
- 2018.12.15 spoj Longest Common Substring II(后缀自动机)
传送门 后缀自动机基础题. 给出10个串求最长公共子串. 我们对其中一个建一个samsamsam,然后用剩下九个去更新范围即可. 代码: #include<bits/stdc++.h> # ...
- spoj 1811 LCS - Longest Common Substring (后缀自己主动机)
spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ...
随机推荐
- springboot 实现自定义注解
1.定义一个注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface T ...
- 面试前需要弄懂的SQL
说明:创建数据库 view source print? 1 Create DATABASE database-name 说明:删除数据库 view source print? 1 drop d ...
- codeforces902B. Coloring a Tree
B. Coloring a Tree 题目链接: https://codeforces.com/contest/902/problem/B 题意:给你一颗树,原先是没有颜色的,需要你给树填色成指定的样 ...
- There is an overlap in the region chain修复
ERROR: (region day_hotstatic,860010-2355010000_20140417_12_entry_00000000321,1400060700465.fda3b0aca ...
- js 内置对象属性及方法
1.Date 属性(1): constructor 所建立对象的函数参考 prototype 能够为对象加入的属性和方法 方法(43): getDay() 返回一周 ...
- Java之戳中痛点 - (3)三目运算符的两个操作数类型尽量一致
先看一个例子: package com.test; public class TernaryOperator { public static void main(String[] args) { in ...
- Java之戳中痛点 - (2)取余用偶判断,不要用奇判断
取余判断原则:取余用偶判断,不要用奇判断 先看一个 程序: package com.test; import java.util.Scanner; public class t1 { public s ...
- vue之axios使用
axios是vue-resource后出现的Vue请求数据的插件.vue更新到2.0之后,作者尤大就宣告不再对vue-resource更新,而是推荐的axios. 下面我们来使用axios npm i ...
- Linux动态库生成以及调用
Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件. 在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是 ...
- POJ 2395 Out of Hay (prim)
题目链接 Description The cows have run out of hay, a horrible event that must be remedied immediately. B ...