bzoj2946: [Poi2000]公共串

SAM处女题qwq

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define N 4096

using namespace std;

struct SAM{
	int last,size;
	struct SAMnode{
		int par,mx,go[26];
		SAMnode(){}
		SAMnode(int _mx):par(0),mx(_mx){
			memset(go,0,sizeof(go));
		}
	} t[N];
	int newnode(int _mx){t[++size]=SAMnode(_mx);return size;}
	void clear(){size=0;last=newnode(0);}
	void extend(char c){
		c-='a';
		int p=last,np=newnode(t[p].mx+1);
		for (;p&&!t[p].go[c];p=t[p].par) t[p].go[c]=np;
		if (!p) t[np].par=1;
		else{
			int q=t[p].go[c];
			if (t[p].mx+1==t[q].mx) t[np].par=q;
			else{
				int nq=newnode(t[p].mx+1);
				memcpy(t[nq].go,t[q].go,sizeof(t[q].go));
				t[nq].par=t[q].par;
				t[q].par=t[np].par=nq;
				for (;p&&t[p].go[c]==q;p=t[p].par) t[p].go[c]=nq;
			}
		}
		last=np;
	}
	int v[N],q[N];
	int ans[N],now[N];
	void precompute(){
		memset(v,0,sizeof(v));
		for (int i=1;i<=size;++i) ++v[t[i].mx];
		for (int i=1;i<=size;++i) v[i]+=v[i-1];
		for (int i=1;i<=size;++i) q[v[t[i].mx]--]=i;
		
		for (int i=1;i<=size;++i) ans[i]=t[i].mx;
	}
	void solve(char *s){
		memset(now,0,sizeof(now));
		int u=1,nowlen=0;
		for (int i=0;s[i];++i){
			while (u&&!t[u].go[s[i]-'a']) u=t[u].par;
			if (!u) nowlen=0,u=1;
			else{
				nowlen=min(nowlen,t[u].mx)+1;
				u=t[u].go[s[i]-'a'];
			}
			now[u]=max(now[u],nowlen);
		}
		for (int i=size;i;--i) now[t[q[i]].par]=max(now[t[q[i]].par],now[q[i]]);
		for (int i=1;i<=size;++i) ans[i]=min(ans[i],now[i]);
	}
	int getans(){
		int ret=0;
		for (int i=1;i<=size;++i) ret=max(ret,ans[i]);
		return ret;
	}
} sam;

int n;
char st[N];
int main(){
	scanf("%d%s",&n,st);
	sam.clear();
	for (int i=0;st[i];++i) sam.extend(st[i]);
	sam.precompute();
	for (int i=1;i<n;++i){
		scanf("%s",st);
		sam.solve(st);
	}
	printf("%d\n",sam.getans());
	return 0;
}

  

posted @ 2016-03-26 16:42  wangyurzee  阅读(240)  评论(0编辑  收藏  举报