POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)
后缀数组:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 typedef long long ll; 7 const int N=2e5+10,mod=998244353; 8 char s[N]; 9 int sa[N],buf1[N],buf2[N],c[N],n,n1,n2,rnk[N],ht[N],ST[N][20],Log[N]; 10 void Sort(int* x,int* y,int m) { 11 for(int i=0; i<m; ++i)c[i]=0; 12 for(int i=0; i<n; ++i)++c[x[i]]; 13 for(int i=1; i<m; ++i)c[i]+=c[i-1]; 14 for(int i=n-1; i>=0; --i)sa[--c[x[y[i]]]]=y[i]; 15 } 16 void da(char* s,int n,int m=300) { 17 int *x=buf1,*y=buf2; 18 x[n]=y[n]=-1; 19 for(int i=0; i<n; ++i)x[i]=s[i],y[i]=i; 20 Sort(x,y,m); 21 for(int k=1; k<n; k<<=1) { 22 int p=0; 23 for(int i=n-k; i<n; ++i)y[p++]=i; 24 for(int i=0; i<n; ++i)if(sa[i]>=k)y[p++]=sa[i]-k; 25 Sort(x,y,m),p=1,y[sa[0]]=0; 26 for(int i=1; i<n; ++i)y[sa[i]]=x[sa[i-1]]==x[sa[i]]&&x[sa[i-1]+k]==x[sa[i]+k]?p-1:p++; 27 if(p==n)break; 28 swap(x,y),m=p; 29 } 30 } 31 void getht() { 32 for(int i=0; i<n; ++i)rnk[sa[i]]=i; 33 ht[0]=0; 34 for(int i=0,k=0; i<n; ++i) { 35 if(k)--k; 36 if(!rnk[i])continue; 37 for(; s[i+k]==s[sa[rnk[i]-1]+k]; ++k); 38 ht[rnk[i]]=k; 39 } 40 } 41 void initST() { 42 for(int i=1; i<n; ++i)ST[i][0]=ht[i]; 43 for(int j=1; (1<<j)<=n; ++j) 44 for(int i=1; i+(1<<j)-1<n; ++i) 45 ST[i][j]=min(ST[i][j-1],ST[i+(1<<(j-1))][j-1]); 46 } 47 int lcp(int l,int r) { 48 if(l==r)return n-sa[l]; 49 if(l>r)swap(l,r); 50 l++; 51 int k=Log[r-l+1]; 52 return min(ST[l][k],ST[r-(1<<k)+1][k]); 53 } 54 int main() { 55 Log[0]=-1; 56 for(int i=1; i<N; ++i)Log[i]=Log[i>>1]+1; 57 scanf("%s",s),n1=strlen(s),s[n1]='|',scanf("%s",s+n1+1),n=strlen(s); 58 da(s,n),getht(),initST(); 59 vector<int> v1,v2; 60 for(int i=0; i<n1; ++i)v1.push_back(rnk[i]); 61 for(int i=n1+1; i<n; ++i)v2.push_back(rnk[i]); 62 sort(v1.begin(),v1.end()); 63 sort(v2.begin(),v2.end()); 64 int ans=0; 65 for(int i=0,j=0; i<v1.size(); ++i) { 66 for(; j<v2.size()&&v2[j]<v1[i]; ++j); 67 if(j-1>=0)ans=max(ans,lcp(v1[i],v2[j-1])); 68 if(j<v2.size())ans=max(ans,lcp(v1[i],v2[j])); 69 } 70 printf("%d\n",ans); 71 return 0; 72 }
后缀自动机:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 const int N=2e5+10,M=26,mod=998244353; 7 char s[N]; 8 int n,fa[N],go[N][M],mxl[N],last,tot; 9 int newnode(int l) {int u=++tot; mxl[u]=l,memset(go[u],0,sizeof go[u]); return u;} 10 void add(int ch) { 11 int p=last,np=last=newnode(mxl[p]+1); 12 for(; ~p&&!go[p][ch]; p=fa[p])go[p][ch]=np; 13 if(!~p)fa[np]=0; 14 else { 15 int q=go[p][ch]; 16 if(mxl[q]==mxl[p]+1)fa[np]=q; 17 else { 18 int nq=newnode(mxl[p]+1); 19 memcpy(go[nq],go[q],sizeof go[q]); 20 fa[nq]=fa[q],fa[q]=fa[np]=nq; 21 for(; ~p&&go[p][ch]==q; p=fa[p])go[p][ch]=nq; 22 } 23 } 24 } 25 int main() { 26 fa[0]=-1; 27 scanf("%s",s),n=strlen(s); 28 for(int i=0; i<n; ++i)add(s[i]-'a'); 29 scanf("%s",s),n=strlen(s); 30 int ans=0; 31 for(int i=0,u=0,l=0; i<n; ++i) { 32 int ch=s[i]-'a'; 33 if(!go[u][ch]) { 34 for(; u&&!go[u][ch]; u=fa[u]); 35 l=mxl[u]; 36 } 37 if(go[u][ch])u=go[u][ch],++l; 38 ans=max(ans,l); 39 } 40 printf("%d\n",ans); 41 return 0; 42 }