题解:
后缀数组
把两个串合并起来
代码:
#include<algorithm> #include<cmath> #include<cstdio> #include<cstring> using namespace std; const int N=200010; int dp[N][33],wa[N],wb[N],wsf[N],wv[N],sa[N],rank[N],height[N],s[N]; char str[N],str1[N]; int cmp(int *r,int a,int b,int k) { return r[a]==r[b]&&r[a+k]==r[b+k]; } void getsa(int *r,int *sa,int n,int m) { int *x=wa,*y=wb; for (int i=0;i<m;i++)wsf[i]=0; for (int i=0;i<n;i++)wsf[x[i]=r[i]]++; for (int i=1;i<m;i++)wsf[i]+=wsf[i-1]; for (int i=n-1;i>=0;i--)sa[--wsf[x[i]]]=i; int p=1,j=1; for (;p<n;j*=2,m=p) { p=0; for (int i=n-j;i<n;i++)y[p++]=i; for (int i=0;i<n;i++) if (sa[i]>=j)y[p++]=sa[i]-j; for (int i=0;i<n;i++)wv[i]=x[y[i]]; for (int i=0;i<m;i++)wsf[i]=0; for (int i=0;i<n;i++)wsf[wv[i]]++; for (int i=1;i<m;i++)wsf[i]+=wsf[i-1]; for (int i=n-1;i>=0;i--)sa[--wsf[wv[i]]]=y[i]; swap(x,y); x[sa[0]]=0; p=1; for (int i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++; } } void getheight(int *r,int n) { int k=0; for (int i=1;i<=n;i++)rank[sa[i]]=i; for (int i=0;i<n;i++) { if (k)k--; int j=sa[rank[i]-1]; while (r[i+k]==r[j+k])k++; height[rank[i]]=k; } } int main() { while (~scanf("%s",str)) { scanf("%s",str1); int n=0,len=strlen(str); for (int i=0;i<len;i++)s[n++]=str[i]-'a'+1; s[n++]=28; len=strlen(str1); for (int i=0;i<len;i++)s[n++]=str1[i]-'a'+1; s[n]=0; getsa(s,sa,n+1,30); getheight(s,n); int maxx=0,pos=0; len=strlen(str); for (int i=2;i<n;i++) if (height[i]>maxx) { if (0<=sa[i-1]&&sa[i-1]<len&&len<sa[i]) maxx=height[i]; if (0<=sa[i]&&sa[i]<len&&len<sa[i-1]) maxx=height[i]; } printf("%d ",maxx); } return 0; }