POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)
题目链接 POJ2774
SPOJ1811 LCS - Longest Common Substring
确实比后缀数组快多了(废话→_→)。
\(Description\)
求两个字符串最长公共子串
\(Solution\)
对串A建立后缀自动机。
A的SAM中包含A的所有子串,且根到每个节点的路径都是A的子串。如果B(的一部分?)匹配到了SAM上的某个节点,那么这便是AB的公共子串。求出这些点的max(len)即可。
用串B在SAM上逐位匹配,如果匹配,就继续沿着匹配边走;
否则,为了匹配当前这位,丢掉B前面一部分,因为fa[p]节点代表的后缀是p所代表后缀的上一个可接受后缀,所以跳fa[p],直到可匹配当前位或到根节点。
注意now的更新方式,如果匹配则+1,否则跳完p后,在p=son[p][c]前用len[p]+1更新now。因为此时p完全匹配了,而len[son[p][c]]是son[p][c]所代表的串的max(len)。(大概是这样吧。。)
感觉这东西好玄学啊。。
//15064K	79MS
//SPOJ:69M	0.04s
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=250005<<1;//2n
char s[N>>1];
struct Suffix_Automaton
{
	int las,tot,son[N][26],fa[N],len[N];
	void Insert(int c)
	{
		int p=las,np=++tot; len[las=np]=len[p]+1;
		for(; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
		if(!p) fa[np]=1;
		else
		{
			int q=son[p][c];
			if(len[q]==len[p]+1) fa[np]=q;
			else
			{
				int nq=++tot; len[nq]=len[p]+1;
				memcpy(son[nq],son[q],sizeof son[q]);
				fa[nq]=fa[q], fa[q]=fa[np]=nq;
				for(; son[p][c]==q; p=fa[p]) son[p][c]=nq;
			}
		}
	}
	void Build(char *s)
	{
		las=tot=1;
		for(int i=0,l=strlen(s); i<l; ++i) Insert(s[i]-'a');
	}
	void Query(char *s)
	{
		int ans=0;
		for(int c,now=0,p=1,i=0,l=strlen(s); i<l; ++i,ans=std::max(ans,now))
			if(son[p][c=s[i]-'a']) p=son[p][c], ++now;
			else
			{
				for(; p&&!son[p][c]; p=fa[p]);
				if(!p) p=1, now=0;
				else now=len[p]+1, p=son[p][c];
//			WA:	else p=son[p][c], now=len[p];
			}
		printf("%d",ans);
	}
}sam;
int main()
{
	scanf("%s",s), sam.Build(s);
	scanf("%s",s), sam.Query(s);
	return 0;
}
一些有关后缀自动机的东西:
论文。。
构造:
后缀自动机详解(感觉这写的理论好理解)
后缀自动机学习小结(从维护right来写?)
后缀自动机学习总结(从简化状态来写?)
后缀自动机构造过程演示(这个过程演示很好啊)
后缀自动机的构造(没看)
题目:
后缀自动机的性质应用
后缀自动机总结
后缀自动机学习小结(应用理论)
几张SAM的例图:
aabbab

aabb

POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)的更多相关文章
- POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀数组 倍增)
		题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 比后缀自动机慢好多(废话→_→). \(Description\) 求两个字符串最长公共子串 ... 
- SPOJ 1811 LCS [后缀自动机]
		题意: 求两个串的最大连续子串 一个串建SAM,另一个串在上面跑 注意如果走了Suffix Link,sum需要更新为t[u].val+1 Suffix Link有点像失配吧,当前状态s走不了了就到S ... 
- spoj 1811 LCS - Longest Common Substring (后缀自己主动机)
		spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ... 
- spoj 1812 lcsII (后缀自动机)
		spoj 1812 lcsII (后缀自动机) 题意:求多个串的lcs,最多10个串,每个串最长10w 解题思路:后缀自动机.先建好第一个串的sam,然后后面的串拿上去跑(这个过程同前一题).sam上 ... 
- [POJ 2774] Long Long Message 【后缀数组】
		题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符 ... 
- POJ 2774 Long Long Message [ 最长公共子串 后缀数组]
		题目:http://poj.org/problem?id=2774 Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total ... 
- ●POJ 2774 Long Long Message
		题链: http://poj.org/problem?id=2774题解: 后缀自动机 使用后缀自动机匹配,思路如下: 即如果当前的x字符匹配失败了,就可以从当前已经匹配的串的后缀去继续匹配. 然后不 ... 
- SPOJ - LCS 后缀自动机入门
		LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set ... 
- Longest Common Substring II SPOJ - LCS2 (后缀自动机)
		Longest Common Substring II \[ Time Limit: 236ms\quad Memory Limit: 1572864 kB \] 题意 给出\(n\)个子串,要求这\ ... 
随机推荐
- Spark记录-Scala异常与处理
			Scala try-catch语句 Scala提供try和catch块来处理异常.try块用于包含可疑代码.catch块用于处理try块中发生的异常.可以根据需要在程序中有任意数量的try...cat ... 
- SQL记录-PLSQL运算符
			PL/SQL运算符 运算符是一个符号,告诉编译器执行特定的数学或逻辑操作. PL/SQL语言有丰富的内置运算符,运算符提供的以下几种类型: 算术运算符 关系运算符 比较运算符 逻辑运算符 字符串运算符 ... 
- oracle connect by用法篇 (转)
			1.基本语法 select * from table [start with condition1] connect by [prior] id=parentid 1 2 1 2 一般用来查找存在父子 ... 
- bzoj千题计划230:bzoj3205: [Apio2013]机器人
			http://www.lydsy.com/JudgeOnline/problem.php?id=3205 历时一天,老子终于把它A了 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 因为不懂spfa ... 
- Lua程序设计(三)面向对象实现一个简单的类
			1.Lua面向对象实现步骤 ①创建一个全局表(称之为元表) ②设置这个元表的__index值(值通常为元表自己,这样就能通过__index查找到对应的属性和方法)__index 赋值其实是一个func ... 
- Does Deep Learning Come from the Devil?
			Does Deep Learning Come from the Devil? Deep learning has revolutionized computer vision and natural ... 
- AngularJs --  模 块
			在JavaScript中,将函数代码全部定义在全局命名空间中绝对不是什么好主意,这样做会导致冲突从而是调试变得非常困难,浪费宝贵的时间. 上一章介绍数据绑定时,就是写在全局命名空间中定义的函数. 在A ... 
- Shell脚本中实现切换用户并执行命令操作【转】
			第一种方法 cat test.sh #!/bin/bashsu - test <<EOFpwd;exit;EOF 执行结果图: 第二种方法 当然也可以用下面的命令来执行 复制代码代码如下: ... 
- Windwos8.1下配置PHP环境
			一. 下载安装包: Apache2.2:http://mirrors.cnnic.cn/apache//httpd/binaries/win32/httpd-2.2.25-win32-x86- ... 
- sonarLint--强大的代码审查工具(插件)
			idea也有的一个插件 贴上一个eclipse的sonarlint用法 http://blog.csdn.net/limm33/article/details/51166840 不过听说从2015年1 ... 
