求出后缀数组和height数组,然后将两个串连接后查找经过且仅经过连接符1次的最大的height的值。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 int n,m,ans,a[N],b[N],h[N],sum[N],ra[N<<1],sa[N]; 5 char s[N],s1[N]; 6 void change(){ 7 for(int i=0;i<n;i++)a[i]=s[i]; 8 memcpy(ra,a,sizeof(a)); 9 sort(a,a+n); 10 m=unique(a,a+n)-a; 11 for(int i=0;i<n;i++)ra[i]=lower_bound(a,a+m,ra[i])-a+1; 12 } 13 void sort(int k){ 14 memset(sum,0,sizeof(sum)); 15 for(int i=0;i<n;i++)sum[ra[i+k]+1]++; 16 for(int i=1;i<=m;i++)sum[i+1]+=sum[i]; 17 for(int i=0;i<n;i++)b[sum[ra[a[i]+k]]++]=a[i]; 18 } 19 void build(){ 20 for(int i=1;;i<<=1){ 21 for(int j=0;j<n;j++)a[j]=j; 22 sort(i); 23 memcpy(a,b,sizeof(a)); 24 sort(0); 25 m=a[b[0]]=1; 26 for(int j=1;j<n;a[b[j++]]=m) 27 if ((ra[b[j-1]]!=ra[b[j]])||(ra[b[j-1]+i]!=ra[b[j]+i]))m++; 28 memcpy(ra,a,sizeof(a)); 29 if (m==n)break; 30 } 31 for(int i=0;i<n;i++)sa[ra[i]]=i; 32 } 33 void height(){ 34 m=0; 35 for(int i=0;i<n;h[ra[i++]]=m,m-=(m>0)) 36 for(int j=sa[ra[i]-1];(i!=j)&&(s[i+m]==s[j+m]);m++); 37 h[1]=0; 38 } 39 int main(){ 40 scanf("%d%s%s",&n,s,s1); 41 n=n*2+1; 42 strcat(s,"0"); 43 strcat(s,s1); 44 change(); 45 build(); 46 height(); 47 ans=1; 48 for(int i=2;i<=n;i++) 49 if ((h[i]>h[ans])&&(1LL*(n/2-sa[i-1])*(n/2-sa[i])<0))ans=i; 50 for(int i=sa[ans];i<sa[ans]+h[ans];i++)printf("%c",s[i]); 51 printf("\n"); 52 }