Spoj LCS2 - Longest Common Substring II

题目描述

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.

输入输出格式

输入格式:

The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.

输出格式:

The length of the longest common substring. If such string doesn‘t exist, print "0" instead.

输入输出样例

输入样例#1:

alsdfkjfjkdsal
fdjskalajfkdsla
aaaajfaaaa

输出样例#1:

2

大概就是要你求最多10个串的最长公共子串,裸上后缀自动机。。。。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define maxn 4000005
using namespace std;
int a[maxn],c[maxn],tot;
int base=1,cnt=1,pre=1,n;
int f[maxn],ch[maxn][26];
int l[maxn],siz[maxn],ans=0;
char s[maxn];

inline void ins(int x){
	int p=pre,np=++cnt;
	pre=np,l[np]=l[p]+1;
	siz[np]=base;

	for(;p&&!ch[p][x];p=f[p]) ch[p][x]=np;
	if(!p) f[np]=1;
	else{
		int q=ch[p][x];
		if(l[q]==l[p]+1) f[np]=q;
		else{
			int nq=++cnt;
			l[nq]=l[p]+1;
			memcpy(ch[nq],ch[q],sizeof(ch[q]));
			f[nq]=f[q];
			f[q]=f[np]=nq;
			for(;ch[p][x]==q;p=f[p]) ch[p][x]=nq;
		}
	}
}

inline void build(){
	n=strlen(s),tot+=n;
	for(int i=0;i<n;i++) ins(s[i]-‘a‘);
}

inline void solve(){
	base--;
	for(int i=1;i<=cnt;i++) c[l[i]]++;
	for(int i=tot;i>=0;i--) c[i]+=c[i+1];
	for(int i=1;i<=cnt;i++) a[c[l[i]]--]=i;

	for(int i=1;i<=cnt;i++){
		int now=a[i];
		siz[f[now]]|=siz[now];
		if(siz[now]==base) ans=max(ans,l[now]);
	}
}

int main(){
	while(scanf("%s",s)==1) build(),base<<=1;
	solve();
	printf("%d\n",ans);
	return 0;
}

  

 

原文地址:https://www.cnblogs.com/JYYHH/p/8458206.html

时间: 2024-10-31 06:26:47

Spoj LCS2 - Longest Common Substring II的相关文章

SPOJ LCS2 - Longest Common Substring II 字符串 SAM

原文链接http://www.cnblogs.com/zhouzhendong/p/8982484.html 题目传送门 - SPOJ LCS2 题意 求若干$(若干<10)$个字符串的最长公共连续子串长度. 串长$\leq 100000$ 题解 建议在做本题之前,先去做SPOJ LCS,本题是其升级版. 题解链接 - SPOJ LCS - http://www.cnblogs.com/zhouzhendong/p/8982392.html 对于本题,我们只需要保持一下之后每一个串在第一个串的$

SPOJ - LCS2 Longest Common Substring II(后缀自动机)题解

题意: 求\(n\)个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,然后枚举所有串.对于每个串,求出这个串在\(i\)节点的最大匹配为\(temp[i]\)(当前串在这个节点最多取多少),然后我们求出最终所有串在\(i\)节点的匹配最小值\(mn[i]\)(即为所有串在\(i\)节点都能取到多少),答案即为\(max\{min[i]\}\). 但是我们能发现,如果我们更新了\(temp[i]\),那么其实\(fa[i]\)的\(temp[fa[i]]\)也应该要更新,因为父节点是我的

spoj 1812 LCS2 - Longest Common Substring II (后缀自动机)

spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 <= n <= 10 |A[i]| <= 1e5 思路: 和spoj 1811 LCS差不多的做法 把其中一个A建后缀自动机 考虑一个状态s, 如果A之外的其他串对它的匹配长度分别是a[1], a[2], ..., a[n - 1], 那么min(a[1], a[2], ..., a[n - 1]

spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 <= n <= 10 |A[i]| <= 1e5 思路: 和spoj 1811 LCS几乎相同的做法 把当中一个A建后缀自己主动机 考虑一个状态s, 假设A之外的其它串对它的匹配长度各自是a[1], a[2], ..., a[n - 1], 那么min(a[1], a[2], ..., a[n -

spoj1812 LCS2 - Longest Common Substring II

地址:http://www.spoj.com/problems/LCS2/ 题面: LCS2 - Longest Common Substring II no tags 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 cons

【SPOJ】Longest Common Substring II (后缀自动机)

[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记录\(f[i]\)表示走到了\(i\)节点 能够匹配上的最长公共子串的长度 当然,每个串的\(f[i]\)可以更新\(f[i.parent]\) 所以需要拓扑排序 对于每个串求出每个节点的最长匹配 然后对他们取\(min\),表示某个节点大家都能匹配的最长长度 最后对于所有点的值都取个\(max\)

【SPOJ】Longest Common Substring II

[SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完后去最小值才是每个点的最终贡献 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm

SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)【两种做法】

手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自动机. 说实话SAM我还没学多么明白. 但是题还是要做的. 说起来这玩意真的很妙.可惜我智商低理解不了. 再次验证了代码能力菜到没边.hyw 30min写完我写2.5h. 题目链接 (洛谷) https://www.luogu.org/problemnew/show/SP1812 题目大意 给\(n

SPOJ 1812 Longest Common Substring II(后缀自动机)

[题目链接] http://www.spoj.com/problems/LCS2/ [题目大意] 求n个串的最长公共子串 [题解] 对一个串建立后缀自动机,剩余的串在上面跑,保存匹配每个状态的最小值, 取最小值中的最大值即可.由于跑的地方只记录了匹配结尾的状态, 所以还需要更新parent树上的状态,既然匹配到了子节点, 那么parent树链上的值就都能够取到l, 一开始给每个不同状态按照l从小到大分配储存地址, 这样,我们就可以从匹配长度最长的开始更新parent树的情况. [代码] #inc