记录编号 170874 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POI 2000] 最长公共子串 最终得分 100
用户昵称 Gravatar天一阁 是否通过 通过
代码语言 C++ 运行时间 0.017 s
提交时间 2015-07-16 20:21:12 内存使用 7.15 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>

#define LL long long
#define N 30010
#define INF 0x3f3f3f3f

using namespace std;

namespace SAM{
	struct node{
		node *ch[26],*fa;
		int len,maxv,minv;
	}*root,spT[N<<1],*now,*b[N<<1];
	
	int tot,ansv;
	int cnt[N];
	
	void init(){
		tot=0;
		root=&spT[++tot];
		now=root;
	}
	
	int idx(char c){
		return c-'a';
	}
	
	void topsort(int n){
		for(int i=1;i<=tot;i++) cnt[spT[i].len]++;
		for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
		for(int i=1;i<=tot;i++) b[cnt[spT[i].len]--]=&spT[i];
		for(int i=1;i<=tot;i++) b[i]->minv=b[i]->len;
	}
	
	void addin(char c){
		int t=idx(c);
		node *np=&spT[++tot],*p=now;
		now=np;
		np->len=p->len+1;
		for(;p&&!p->ch[t];p=p->fa) p->ch[t]=np;
		if(!p) np->fa=root;
		else{
			if(p->ch[t]->len==p->len+1) np->fa=p->ch[t];
			else{
				node* nq=&spT[++tot],*q=p->ch[t];
				*nq=*q;
				q->fa=np->fa=nq;
				nq->len=p->len+1;
				for(;p&&p->ch[t]==q;p=p->fa)
					p->ch[t]=nq;
			}
		}
	}
	
	void ask(char *S,int n){
		node* p=root;
		int tmp=0;
		for(int i=1;i<=tot;i++) b[i]->maxv=0;
		for(int i=0;i<n;i++){
			int t=idx(S[i]);
			if(p->ch[t]) tmp++,p=p->ch[t];
			else{
				for(;p&&!p->ch[t];p=p->fa);
				if(!p) p=root,tmp=0;
				else tmp=p->len+1,p=p->ch[t];
			}
			p->maxv=max(p->maxv,tmp);
		}
		ansv=0;
		for(int i=tot;i>=1;i--){
			node* tmp=b[i];
			if(tmp->fa) tmp->fa->maxv=max(tmp->fa->maxv,tmp->maxv);
			tmp->minv=min(tmp->minv,tmp->maxv);
			ansv=max(ansv,tmp->minv);
		}
	}
}

char S[N];
int n;

int main(){
	freopen("pow.in","r",stdin);
	freopen("pow.out","w",stdout);
	scanf("%d",&n);
	scanf("%s",S);
	n=strlen(S);
	SAM::init();
	for(int i=0;i<n;i++) SAM::addin(S[i]);
	SAM::topsort(n);
	while(scanf("%s",S)==1){
		n=strlen(S);
		SAM::ask(S,n);
	}
	printf("%d\n",SAM::ansv);
	fclose(stdin);
	fclose(stdout);
	return 0;
}