第二道后缀数组…其实感觉比上一道简单【23333
后缀数组的主要用法之一就是height[]…
这道题就是把两个字符串用分隔符连接起来,求新字符串的height[],然后找到有效height的最大值即可【有效height就是该height对应的两个串分别在两个字符串中
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100005*2;
const int maxm=maxn;
char str[maxn];
int l1,l2,ans;
int num[maxn],sa[maxn],rank[maxn],height[maxn];
int wa[maxn],wb[maxn],wv[maxn],cnt[maxm];
void DA(int *r,int n,int m)
{
int *x=wa,*y=wb,p;
for(int i=0;i<m;i++)cnt[i]=0;
for(int i=0;i<n;i++)cnt[x[i]=r[i]]++;
for(int i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;i--)sa[--cnt[x[i]]]=i;
for(int j=1;j<n;j<<=1)
{
p=0;
for(int i=n-j;i<n;i++)y[p++]=i;
for(int i=0;i<n;i++)if(sa[i]-j>=0)y[p++]=sa[i]-j;
for(int i=0;i<n;i++)wv[i]=x[y[i]];
for(int i=0;i<m;i++)cnt[i]=0;
for(int i=0;i<n;i++)cnt[wv[i]]++;
for(int i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;i--)sa[--cnt[wv[i]]]=y[i];
swap(x,y);
p=1;x[sa[0]]=0;
for(int i=1;i<n;i++)
x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+j]==y[sa[i-1]+j])?p-1:p++;
if(p>=n)break;
m=p;
}
for(int i=1;i<n;i++)
rank[sa[i]]=i;
}
void calheight(int *r,int n)
{
int j=0,k=0;
for(int i=0;i<n;height[rank[i]]=k,i++)
for(k?k--:k=0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
}
int main(void)
{
scanf("%s",str);
l1=strlen(str);
for(int i=0;i<l1;i++)
num[i]=str[i]-'a'+2;
num[l1]=1;
scanf("%s",str);
l2=strlen(str);
for(int i=0;i<l2;i++)
num[l1+i+1]=str[i]-'a'+2;
l2+=l1+1;
DA(num,l2+1,30);
calheight(num,l2);
for(int i=2;i<l2;i++)
if((sa[i]<l1 && sa[i-1]>l1) || (sa[i]>l1 && sa[i-1]<l1))
ans=max(ans,height[i]);
printf("%d\n",ans);
return 0;
}