卧薪尝胆,厚积薄发。
POI2000 公共串
Date: Fri Aug 17 14:17:27 CST 2018 In Category: NoCategory

Description:

给出 $n$ 个由小写字母构成的单词,求它们最长的公共子串的长度。
$1\le n \le 5$ $1\le len \le 2000$

Solution:

对第一个串建出后缀自动机,其他串在上面跑,对每个点记录一下 $len$ ,刚开始为 $maxl$ ,之后每个串跑的时候记一下到每个点时的 $len$ 中的最大值,就像求两个串的最长公共子串一样,在跑完后统一用 $maxlen$ 对 $len$ 取 $min$ ,注意在跳 $par$ 时,第一次不能用 $maxl$ 更新 $maxlen$ ,因为可能没有跑满,但跳了一次 $par$ 之后就可以了,因为有 $maxl_{par}+1=minl_{cur}$ ,所以一定满足。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n;
#define MAXL 2010
char c[MAXL];
struct node
{
int tr[26],maxl,par;
}s[MAXL << 1];
int lenth[MAXL << 1];
int last = 1,root = 1,ptr = 1;
int newnode(int k){++ptr;s[ptr].maxl = k;return ptr;}
void extend(int k)
{
int p = last;
int np = newnode(s[p].maxl + 1);
for(;p && s[p].tr[k] == 0;p = s[p].par)s[p].tr[k] = np;
if(p == 0)s[np].par = root;
else
{
int q = s[p].tr[k];
if(s[p].maxl + 1 == s[q].maxl)s[np].par = q;
else
{
int nq = newnode(s[p].maxl + 1);
memcpy(s[nq].tr,s[q].tr,sizeof(s[q].tr));
s[nq].par = s[q].par;
s[q].par = s[np].par = nq;
for(;p && s[p].tr[k] == q;p = s[p].par)s[p].tr[k] = nq;
}
}
last = np;
return;
}
int cnt[MAXL << 1];
void solve(char c[])
{
memset(cnt,0,sizeof(cnt));
int l = strlen(c + 1);
int p = root;
int sum = 0;
for(int i = 1;i <= l;++i)
{
if(s[p].tr[c[i] - 'a'] != 0)
{
p = s[p].tr[c[i] - 'a'];
++sum;
cnt[p] = max(cnt[p],sum);
}
else
{
for(;p && s[p].tr[c[i] - 'a'] == 0;p = s[p].par);
if(p == 0)
{
p = root;
sum = 0;
}
else
{
cnt[p] = max(cnt[p],s[p].maxl);
sum = s[p].maxl + 1;
p = s[p].tr[c[i] - 'a'];
cnt[p] = max(cnt[p],sum);
}
}
}
for(int i = 1;i <= ptr;++i)lenth[i] = min(lenth[i],cnt[i]);
return;
}
int main()
{
scanf("%d",&n);
--n;
scanf("%s",c + 1);
int l = strlen(c + 1);
for(int i = 1;i <= l;++i)extend(c[i] - 'a');
for(int i = 1;i <= ptr;++i)lenth[i] = s[i].maxl;
for(int i = 1;i <= n;++i)
{
scanf("%s",c + 1);
solve(c);
}
int ans = 0;
for(int i = 1;i <= ptr;++i)ans = max(lenth[i],ans);
cout << ans << endl;
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡