poj2774 后缀数组 求最长公共子串

时间:2023-03-10 02:14:30
poj2774  后缀数组   求最长公共子串

Reference:IOI2009论文

http://www.cnblogs.com/ziyi--caolu/p/3192731.html

 #include "stdio.h"
#include "string.h"
#define maxn 200010 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
int rank[maxn],height[maxn];
int r[maxn],sa[maxn];
char s1[],s2[];
int n,l1,l2,ans; int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
} void da(int *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) ws[i]=;
for(i=; i<n; i++) ws[x[i]=r[i]]++;
for(i=; i<m; i++) ws[i]+=ws[i-];
for(i=n-; i>=; i--) sa[--ws[x[i]]]=i;
for(j=,p=; p<n; j*=,m=p)
{ for(p=,i=n-j; i<n; i++) y[p++]=i;
for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=; i<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) ws[i]=;
for(i=; i<n; i++) ws[wv[i]]++;
for(i=; i<m; i++) ws[i]+=ws[i-];
for(i=n-; i>=; i--) sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
} void calheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=; i<=n; i++) rank[sa[i]]=i;
for(i=; i<n; height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-]; r[i+k]==r[j+k]; k++);
return;
} bool _same(int lx,int ly,int l1,int l2)
{
return (((lx<=l1-) && (ly>=l1+))||((ly<=l1-) && (lx>=l1+)));
} //da(r,sa,n+1,128);
//calheight(r,sa,n);
int main()
{
scanf("%s",s1);
l1=strlen(s1);
scanf("%s",s2);
l2=strlen(s2);
for (int i=;i<l1;i++)
{
char ch=s1[i];
int tmp=ch-'a'+;
r[i]=tmp;
}
r[l1]=;
for (int i=l1+;i<l1+l2+;i++)
{
char ch=s2[i-l1-];
int tmp=ch-'a'+;
r[i]=tmp;
}
n=l1+l2+;
r[n]=; da(r,sa,n+,);
calheight(r,sa,n); ans=;
for (int i=;i<=n;i++)
{
int t1=sa[i],t2=sa[i-];
if (_same(t1,t2,l1,l2))
{
if (height[i]>ans)
ans=height[i];
}
}
printf("%d\n",ans); return ;
}