题意:求多个字符串的最长公共子串
#include<stdio.h>
#include<string.h>
#define r 805000
char str[201],ans[201];
int s[r],a[r],b[r],c[r],e[r],id[r],f[r],h[r],visit[4001];
void getsa(int n,int m)
{
int i,j,p,*x=e,*y=f,*t;
for(i=0;i<m;i++) b[i]=0;
for(i=0;i<n;i++) b[x[i]=s[i]]++;
for(i=1;i<m;i++) b[i]+=b[i-1];
for(i=n-1;i>=0;i--) a[--b[x[i]]]=i;
for(p=1,j=1;p<n;j*=2,m=p)
{
for(p=0,i=n-j;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(a[i]>=j) y[p++]=a[i]-j;
for(i=0;i<n;i++) c[i]=x[y[i]];
for(i=0;i<m;i++) b[i]=0;
for(i=0;i<n;i++) b[c[i]]++;
for(i=1;i<m;i++) b[i]+=b[i-1];
for(i=n-1;i>=0;i--) a[--b[c[i]]]=y[i];
for(p=1,i=1,t=x,x=y,y=t,x[a[0]]=0;i<n;i++)
x[a[i]]=(y[a[i]]==y[a[i-1]]&&y[a[i]+j]==y[a[i-1]+j])?p-1:p++;
}
}
void getheight(int n)
{
int i,j,k=0;
for(i=1;i<=n;i++) b[a[i]]=i;
for(i=0;i<n;i++)
{
if(k) k--;
else k=0;
j=a[b[i]-1];
while(s[i+k]==s[j+k]) k++;
h[b[i]]=k;
}
}
int check(int m,int k,int n)
{
int i,j,t=0;
memset(visit,0,sizeof(visit));
for(i=2;i<=n;i++)
{
if(h[i]<k)
{
t=0;
memset(visit,0,sizeof(visit));
continue;
}
if(!visit[id[a[i]]])
{
t++;
visit[id[a[i]]]=1;
}
if(!visit[id[a[i-1]]])
{
t++;
visit[id[a[i-1]]]=1;
}
if(t==m)
{
for(j=0;j<k;j++)
{
ans[j]=s[a[i]+j]+'a'-1;
}
ans[k]='\0';
return 1;
}
}
return 0;
}
int main()
{
int n,m,i,j,t,k;
while(~scanf("%d",&n),n)
{
t=0;k=r;
for(i=0;i<n;i++)
{
scanf("%s",str);
for(j=0;str[j]!='\0';j++)
{
s[t]=str[j]-'a'+1;
id[t++]=i;
}
k=k<j?k:j;
s[t]=30+i;
id[t++]=30+i;
}
s[t]=0;
getsa(t+1,30+n+1);
getheight(t);
i=0;j=k;
m=0;
while(i<=j)
{
k=(i+j)/2;
if(check(n,k,t))
{i=k+1;m=k;
}
else j=k-1;
}
if(m) printf("%s\n",ans);
else printf("IDENTITY LOST\n");
}
return 0;
}