SPOJ 1812 LCS2 字尾自動機
阿新 • • 發佈:2019-01-26
求給定n個串的最長公共子串。
先對一個構造SAM。
接著每個串匹配一次,並處理出各狀態能匹配到的最大長度(要注意沿Parent樹更新),於是總的就是各狀態的最小值。
#include <cstring>
#include <cstdio>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define FOR(i,j,k) for(i=j;i<=k;++i)
const int rt = 1, N = 200005;
int last = 1 , cnt = 1, len = 0;
int ch[N][26], fa[N], ma[N], rl[N], rr[N], b[N], bucket[N >> 1];
char str[N >> 1];
void add(char c) {
int np = ++cnt, p = last, q, nq; last = np; rl[np] = rr[np] = ma[np] = ++len;
while (p && !ch[p][c]) ch[p][c] = np, p = fa[p];
if (!p) fa[np] = rt;
else {
q = ch[p][c];
if (ma[q] == ma[p] + 1) fa[np] = q;
else {
nq = ++cnt; memcpy(ch[nq], ch[q], sizeof ch[q]);
rl[nq] = ma[nq] = ma[p] + 1;
fa[nq] = fa[q]; fa[q] = fa[np] = nq;
while (p && ch[p][c] == q) ch[p][c] = nq, p = fa[p];
}
}
}
int main() {
int i, n, p, y, c, ans = 0;
scanf("%s", str + 1); n = strlen(str + 1);
for(i=1;str[i];++i) add(str[i] - 'a');
FOR(i,1,cnt) ++bucket[ma[i]];
FOR(i,1,n) bucket[i] += bucket[i - 1];
for(i=cnt;i;--i) b[bucket[ma[i]]--] = i;
while (scanf("%s", str + 1) != EOF) {
p = rt; y = 0;
for(i=1;str[i];++i) {
c = str[i] - 'a';
if (ch[p][c]) {
p = ch[p][c];
rr[p] = max(rr[p], ++y);
} else {
while (p && !ch[p][c]) p = fa[p];
if (p) rr[p] = max(rr[p], y = ma[p] + 1), p = ch[p][c];
else p = rt, y = 0;
}
}
for(i=cnt;i;--i) {
rl[b[i]] = min(rl[b[i]], rr[b[i]]);
rr[fa[b[i]]] = max(rr[fa[b[i]]], rr[b[i]]);
rr[b[i]] = 0;
}
}
FOR(i,1,cnt) ans = max(ans, rl[i]);
printf("%d", ans);
return 0;
}
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