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写的. 注意!(对拍的时候发现)这份代码没有对只有一个字符串的情况进行处理! ...
随机推荐
- NewCode
1.[数论]给你N,求不大于N的最大完全平方数. #include<bits/stdc++.h> #define FOR(i,a,b) for(int i=(a),_b=(b);i< ...
- HDFS Scribe Integration 【转】
It is finally here: you can configure the open source log-aggregator, scribe, to log data directly i ...
- Break Number --AtCoder
题目描述 Takahashi loves numbers divisible by 2.You are given a positive integer N. Among the integers b ...
- 笔记-迎难而上之Java基础进阶8
函数式接口 函数式接口:有且只有一个抽象方法的接口,(可以包含其他默认,静态,私有方法) //函数式接口的使用,创建一个函数式接口 public interface FunctionalInterfa ...
- ios界面笔记(一)
基于一个简单视图的view解析
- HDU4004
题目大意,有一条长度为L和河流,中间穿插n个石凳,青蛙跳m次经过石凳后到达对岸,求青蛙每次跳跃的最大距离的最小值 本题数据量大n<500000,显然简单的o(n*n)算法是通过不了的,在输入大量 ...
- 查找python项目依赖并生成requirements.txt
1.如果使用virtualenv环境,直接使用 pip freeze > requirements.txt ➜ ~ .virtualenvs/xxx/bin/pip freeze > r ...
- MFC中 编辑框输入换行功能
首先修改编辑框的属性: Multiline 设为true , Auto HScroll 设为true , Auto VScroll 设为 true . 然后响应PreTranslateMessage( ...
- EasyMvc入门教程-高级控件说明(15)方位布局控件
现在很多管理后台都流行全屏切割的布局,大体结构如下图所示: 大家注意到没,整个布局是五个部分组成:“东西南北中”,EasyMvc对应的实现的代码为: @(Html.Q().Layout().TextC ...
- su、sudo、sudo su、sudo -i的用法和区别
sudo : 暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.不过有时间限制,Ubuntu默认为一次时长15分钟.su : 切换到某某用户模式,提 ...