SPOJ LCS2 - Longest Common Substring II 后缀自动机 多个串的LCS
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.
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
Notice: new testcases added
题意:
求多个串的最长公共字串
题解:
将第一个串建立后缀自动机
根据拓扑排序更新每个状态节点下所能向前延伸的长度,每次匹配一个串都更新即可
是不是很模糊
#include <bits/stdc++.h>
inline long long read(){long long x=,f=;char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return x*f;}
using namespace std; const int N = 3e5+; const long long mod = ; int isPlus[N * ],endpos[N * ];int d[N * ];
int tot,slink[*N],trans[*N][],minlen[*N],maxlen[*N],pre;
int newstate(int _maxlen,int _minlen,int* _trans,int _slink){
maxlen[++tot]=_maxlen;minlen[tot]=_minlen;
slink[tot]=_slink;
if(_trans)for(int i=;i<;i++)trans[tot][i]=_trans[i],d[_trans[i]]+=;
return tot;
}
int add_char(char ch,int u){
int c=ch-'a',v=u;
int z=newstate(maxlen[u]+,-,NULL,);
isPlus[z] = ;
while(v&&!trans[v][c]){trans[v][c]=z;d[z]+=;v=slink[v];}
if(!v){ minlen[z]=;slink[z]=;return z;}
int x=trans[v][c];
if(maxlen[v]+==maxlen[x]){slink[z]=x;minlen[z]=maxlen[x]+;return z;}
int y=newstate(maxlen[v]+,-,trans[x],slink[x]);
slink[z]=slink[x]=y;minlen[x]=minlen[z]=maxlen[y]+;
while(v&&trans[v][c]==x){trans[v][c]=y;d[x]--,d[y]++;v=slink[v];}
minlen[y]=maxlen[slink[y]]+;
return z;
}
void init_sam() {
for(int i = ; i <= tot; ++i)
for(int j = ; j < ; ++j) trans[i][j] = ;
pre = tot = ;
} int dp[N],ans,n,vis[N],cnt[N],pos[N];
char a[N];
int main() {
int f = ;
while(scanf("%s",a)!=EOF) {
n = strlen(a);
if(f) {
init_sam();
for(int i = ; i < n; ++i)
pre = add_char(a[i],pre);
f = ;
for(int i = ; i <= n; ++i)cnt[i] = ;
for(int i = ; i <= tot; ++i)cnt[maxlen[i]] += ;
for(int i = ; i <= n; ++i)cnt[i]+=cnt[i-];
for(int i = tot; i >= ; --i)pos[cnt[maxlen[i]]--] = i;
}
else
{
int now = ,sum = ;
for(int i = ; i < n; ++i)
{
if(trans[now][a[i]-'a']) {
sum++;
now = trans[now][a[i]-'a'];
dp[now] = max(dp[now],sum);
}
else {
while(now) {
now = slink[now];
if(trans[now][a[i]-'a']) break;
}
if(!now) now = ,sum = ;
else
{
sum = maxlen[now] + ;
now = trans[now][a[i]-'a'];
dp[now] = max(dp[now],sum);
}
}
}
for(int i = tot; i >= ; --i) {
int v = pos[i];
maxlen[v] = min(maxlen[v],dp[v]);
dp[slink[v]] = max(dp[slink[v]],dp[v]);
dp[v] = ;
}
}
}
int ans = ;
for(int i = ; i <= tot; ++i) {
ans = max(ans,maxlen[i]);
}
printf("%d\n",ans);
return ;
}
/*
aabbcd
babbefg
cdbbabb
*/
SPOJ LCS2 - Longest Common Substring II 后缀自动机 多个串的LCS的更多相关文章
- 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 人生第一道后缀自 ...
- [SPOJ1812]Longest Common Substring II 后缀自动机 多个串的最长公共子串
题目链接:http://www.spoj.com/problems/LCS2/ 其实两个串的LCS会了,多个串的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 < ...
- SPOJ LCS2 - Longest Common Substring II
LCS2 - Longest Common Substring II A string is finite sequence of characters over a non-empty finite ...
- SPOJ - LCS2 Longest Common Substring II(后缀自动机)题解
题意: 求\(n\)个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,然后枚举所有串.对于每个串,求出这个串在\(i\)节点的最大匹配为\(temp[i]\)(当前串在这个节点最多取多少), ...
- SPOJ LCS2 - Longest Common Substring II 字符串 SAM
原文链接http://www.cnblogs.com/zhouzhendong/p/8982484.html 题目传送门 - SPOJ LCS2 题意 求若干$(若干<10)$个字符串的最长公共 ...
- Virtual Judge SPOJ - LCS2 Longest Common Substring II
https://vjudge.net/problem/SPOJ-LCS2 SPOJ注册看不到验证码,气到暴毙,用vjudge写的. 注意!(对拍的时候发现)这份代码没有对只有一个字符串的情况进行处理! ...
随机推荐
- hdu 4519(数学题)
郑厂长系列故事——体检 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total S ...
- LeetCode OJ--Copy List with Random Pointer **
https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 灵活的指针链表应用. 每个节点有两个指针next,random,对本链表 ...
- JavaScript的Object
题目 var foo = new Object(); var bar = new Object(); var map = new Object(); map[foo] = "foo" ...
- 打包python脚本为exe
更新pip 安装
- linux 项目管理、服务器管理、服务器维护
代码打包:tar -zcvf ImOra.3.2.6.tgz --exclude=Public/.htaccess --exclude=Apps/Demo Apps/ Config/ Shell/ L ...
- 3 Suggested Oracle Certifications For Oracle Form's Developers
The following are the most suggested Oracle Certifications for Oracle Application Developers in Form ...
- Android 监听双卡信号强度(附完整代码)
Android 监听双卡信号强度 监听单卡信号强度 监听单卡的信号强度非常简单直接用TelephonyManager.listen()去监听sim卡的信号强度. TelephonyManager = ...
- django常用第三方app大全
djangoapp 资源大全 最近经常在这个版面看到Django相关扩展的介绍,而其一个扩展写一个帖子,觉得没太必要吧. 以前整理的django资源列表,从我的wiki上转过来的. 要找django资 ...
- C语言对文件的读写操作以及处理CSV文件的方法
#include <stdio.h> #define F_PATH "d:\myfile\file.txt" int main(void) { FILE *fp = N ...
- 【前端阅读】——《活用PHP、MySQL建构Web世界》摘记之设计技巧
二.设计技巧 Programming的习惯因人而异,这里只提供一些经验,可以参考. 1.利用Include模块化你的程序代码 Include函数基本上说:就像是把另一个文件(HTML或者PHP程序)读 ...