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; }