题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2774 #include "iostream" #include "cstring" using namespace std; const int MaxN=210000+100; int SA[MaxN],Rank[MaxN*2],D[MaxN*2],Count_Rank[MaxN*2]; int Height[MaxN]; int N,M,K,Len1,Len2; char A[MaxN],S[MaxN],S1[MaxN],S2[MaxN]; int B[MaxN],List[MaxN],P; void input(){ scanf("%s",S+1); Len1=strlen(S+1); ++Len1; S[Len1]='#'; //puts(S+1); scanf("%s",S+Len1+1); N=strlen(S+1); ++N; S[N]=0; //puts(S+1); } void ssort(){ int i,j,L,k; memset(D,0,sizeof(D)); memset(SA,0,sizeof(SA)); memset(Rank,0,sizeof(D)); memset(Count_Rank,0,sizeof(D)); sort(A+1,A+N+1); for(i=1;i <=N;++i) Rank[i]=lower_bound(A,A+N+1,S[i])-A; for(L=1;L <N; L*=2){ memset(Count_Rank,0,sizeof(Count_Rank)); for(i=1;i <=N;++i) Count_Rank[Rank[i+L]]++; for(i=1;i <=N;++i) Count_Rank[i]+=Count_Rank[i-1]; for(i=N;i >0; --i) D[Count_Rank[Rank[i+L]]--]=i; memset(Count_Rank,0,sizeof(Count_Rank)); for(i=1;i <=N;++i) Count_Rank[Rank[i]]++; for(i=1;i <=N;++i) Count_Rank[i]+=Count_Rank[i-1]; for(i=N;i >0; --i) SA[Count_Rank[Rank[D[i]]]--]=D[i]; memcpy(D,Rank,sizeof(Rank)); Rank[SA[1]]=k=1; for(i=2;i <=N;++i){ if( D[SA[i]] != D[SA[i-1]] || D[SA[i]+L] !=D[SA[i-1]+L]) k++; Rank[SA[i]]=k; } } k=0; for(i=1;i <=N;++i){ if(Rank[i]==N) { Height[N]=k=0; continue;} j=SA[Rank[i]+1]; for(k=max(k-1,0); S[i+k]==S[j+k];k++); Height[Rank[i]]=k; } } int main(){ int i,j,k; input(); //printf("N=%d/n",N); //puts(S+1); memcpy(A,S,sizeof(S)); ssort(); int p1,p2,ans=-1; /*for(int i=1;i <=N;++i) printf("i=%d %d/n",i,S[i]);*/ /*for(int i=1;i <N;++i){ printf("Height[i]=%d ",Height[i]); printf("SA[i]=%d SA[i+1]=%d %s/n",SA[i],SA[i+1],S+SA[i]); }*/ for(int i=1;i <N;++i){ j=SA[i]; if(j <Len1) p1=1; else p1=-1; k=SA[i+1]; //printf("j=%d k=%d Height[i]=%d/n",j,k,Height[i]); if(k <Len1) p2=1; else p2=-1; if( p1 * p2< 1 && Height[i]> ans) ans=Height[i]; } printf("%d/n",ans); return 0; } 将两个字符串连接成一个字符串, 求该字符串的后缀数组, 然后求分别位于两个串中的Height数组的最大值,即为所求答案。