1. 程式人生 > >SPOJ 1812 LCS2 字尾自動機

SPOJ 1812 LCS2 字尾自動機

求給定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