spoj1812-Longest Common Substring II(后缀自动机)
Description
A string is finite sequence of characters over a non-empty finite set Σ.
In this problem, Σ is the set of lowercase letters.
Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.
Now your task is a bit harder, for some given strings, find the length of the longest common substring of them.
Here common substring means a substring of two or more strings.
Input
The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.
Output
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Example
Input:
alsdfkjfjkdsal
fdjskalajfkdsla
aaaajfaaaa Output:
2
题意:给若干个字符串,长度不超过100000,求最长公共连续字串
解析:后缀自动机,对输入的第一个字符串建一个后缀自动机,在
sam中添加两个量Max[i](查询时以第i个节点为最后一个字符的后缀的最大长度)
,Min[i](所有查询Max[i]中的最小值)。
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=;
struct SAM
{
int ch[maxn][];
int pre[maxn],step[maxn];
int last,id;
int Min[maxn],Max[maxn];
void init() //初始化
{
last=id=;
memset(ch[],-,sizeof(ch[]));
pre[]=-; step[]=;
Min[]=Max[]=;
}
void Insert(int c) //模板,自己百度
{
int p=last,np=++id;
step[np]=step[p]+;
memset(ch[np],-,sizeof(ch[np]));
Min[np]=Max[np]=step[np];
while(p!=-&&ch[p][c]==-) ch[p][c]=np,p=pre[p];
if(p==-) pre[np]=;
else
{
int q=ch[p][c];
if(step[q]!=step[p]+)
{
int nq=++id;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
step[nq]=step[p]+;
Min[nq]=Max[nq]=step[nq];
pre[nq]=pre[q];
pre[np]=pre[q]=nq;
while(p!=-&&ch[p][c]==q) ch[p][c]=nq,p=pre[p];
}
else pre[np]=q;
}
last=np;
}
void Find(char *S)
{
int len=strlen(S);
int u=,d=;
for(int i=;i<=id;i++) Max[i]=;
for(int i=;i<len;i++)
{
int c=S[i]-'a';
if(ch[u][c]!=-) d++,u=ch[u][c];
else
{
while(u!=-&&ch[u][c]==-) u=pre[u];
if(u!=-) d=step[u]+,u=ch[u][c];
else u=,d=;
}
Max[u]=max(Max[u],d);//更新
}
for(int i=id;i>=;i--) Max[pre[i]]=max(Max[pre[i]],Max[i]);
for(int i=;i<=id;i++) Min[i]=min(Min[i],Max[i]);
}
int GetAns()
{
int ret=;
for(int i=;i<=id;i++) ret=max(ret,Min[i]);
return ret;
}
}sam;
char S[maxn];
int main()
{
scanf("%s",S);
int len=strlen(S);
sam.init();
for(int i=;i<len;i++) sam.Insert(S[i]-'a');
while(scanf("%s",S)!=EOF) sam.Find(S);
printf("%d\n",sam.GetAns());
return ;
}
spoj1812-Longest Common Substring II(后缀自动机)的更多相关文章
- [SPOJ1812]Longest Common Substring II 后缀自动机 多个串的最长公共子串
题目链接:http://www.spoj.com/problems/LCS2/ 其实两个串的LCS会了,多个串的LCS也就差不多了. 我们先用一个串建立后缀自动机,然后其它的串在上面跑.跑的时候算出每 ...
- SPOJ LCS2 - Longest Common Substring II 后缀自动机 多个串的LCS
LCS2 - Longest Common Substring II no tags A string is finite sequence of characters over a non-emp ...
- 2018.12.15 spoj1812 Longest Common Substring(后缀自动机)
传送门 后缀自动机模板题. 题意简述:求两个字串的最长公共子串长度. 对其中一个构建后缀自动机,用另外一个在上面跑即可. 代码: #include<bits/stdc++.h> #defi ...
- SPOJ LCS2 Longest Common Substring II ——后缀自动机
后缀自动机裸题 #include <cstdio> #include <cstring> #include <iostream> #include <algo ...
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)
手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自 ...
- 【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 < ...
- SPOJ1812 Longest Common Substring II
题意 A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is th ...
- HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)
Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...
随机推荐
- Engineering Economics
相关简介 工程经济学 –-研究各种技术在使用过程中如何以最小的投入获得预期产出或者说如何以等量的投入获得最大的产出: –-如何用最低的寿命周期成本实现产品.作业以及服务的必要功能. 软件工程经济学 工 ...
- form表单提交之前推断
1.使用onsubmit方法 <form name="Form" action="t" method="post" onsubmit= ...
- CCSpawn使用CCRepeatForever无效
在使用CCSpawn中加入CCRepeatForever,但却无法使用CCRepeatForever的效果. CCActionInterval* action =(CCActionInterval*) ...
- linux 常用find命令
1.查找当前目录下以test开头的所有文件-会进入子目录中去查找 [root@rusky hgfs]# find -name test* 2.查找当前目录下名为test.txt的文件-会进入子目录中去 ...
- 自定义控件 环形进度条 ProgressBar
使用 public class MainActivity extends Activity implements OnComompleteListener { private int num ...
- NumberBox( 数值输入框) 组件
本节课重点了解 EasyUI 中 NumberBox(数值输入框)组件的使用方法,这个组件依赖于 ValidateBox(验证框)组件.一. 加载方式//class 加载方式<input typ ...
- 关于R文件丢失的一个问题
android studio在编辑布局文件时,一般为了省事,如TextView控件中的text属性这样写 android:text="<500",编译不会报错,但是运行时会出 ...
- USB OTG to PC USB API简介
本API分为四部分:Linux或Android内核 (主要是gadget驱动).linux端API及其DEMO.Windows 驱动.Windows API及其Demo. 一.linux.Androi ...
- C++ list用法
创建一个list实例并赋值: // 创建实例以及赋值 #include <iostream> #include <list> using namespace std; int ...
- (原)python中matplot中获得鼠标点击的位置及显示灰度图像
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6182474.html 参考网址: http://matplotlib.org/examples/pyl ...