记录编号 379636 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POI 2000] 最长公共子串 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 0.048 s
提交时间 2017-03-07 07:22:41 内存使用 24.51 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200010;
void expand(int);
void match(const char*);
int root,last,cnt=0,val[maxn]={0},par[maxn]={0},go[maxn][26]={{0}},a[maxn],b[maxn];
char s[maxn];
int T,n,c[maxn>>1]={0},d[maxn],tim=0,ans=0;
int main(){
	freopen("pow.in","r",stdin);
	freopen("pow.out","w",stdout);
	memset(b,63,sizeof(b));
	root=last=++cnt;
	scanf("%d%s",&T,s);
	n=strlen(s);
	for(int i=0;i<n;i++)expand(s[i]-'a');
	for(int i=1;i<=cnt;i++)c[val[i]+1]++;
	for(int i=1;i<=n;i++)c[i]+=c[i-1];
	for(int i=1;i<=cnt;i++)d[++c[val[i]]]=i;
	while(--T){
		scanf("%s",s);
		match(s);
	}
	for(int i=1;i<=cnt;i++)ans=max(ans,b[i]);
	printf("%d\n",ans);
	return 0;
}
void expand(int c){
	int p=last,np=++cnt;
	val[np]=val[p]+1;
	while(p&&!go[p][c]){
		go[p][c]=np;
		p=par[p];
	}
	if(!p)par[np]=root;
	else{
		int q=go[p][c];
		if(val[q]==val[p]+1)par[np]=q;
		else{
			int nq=++cnt;
			val[nq]=val[p]+1;
			memcpy(go[nq],go[q],sizeof(go[q]));
			par[nq]=par[q];
			par[np]=par[q]=nq;
			while(p&&go[p][c]==q){
				go[p][c]=nq;
				p=par[p];
			}
		}
	}
	last=np;
}
void match(const char *c){
	fill(a,a+cnt+1,0);
	for(int x=root,len=0;*c;c++){
		while(x&&!go[x][*c-'a']){
			x=par[x];
			len=val[x];
		}
		if(!x){
			x=root;
			len=0;
		}
		else{
			x=go[x][*c-'a'];
			len++;
		}
		a[x]=max(a[x],len);
	}
	for(int i=1;i<=cnt;i++)b[i]=min(b[i],a[i]);
	for(int i=cnt;i;i--)b[par[d[i]]]=max(b[par[d[i]]],b[d[i]]);
}