Time Limit: 4000MS | Memory Limit: 131072K | |
Total Submissions: 30427 | Accepted: 12337 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
Source
#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> using namespace std; /****************************************后缀数组模板****************************************/ const int maxn=1000000+100; struct SuffixArray { char s[maxn]; int sa[maxn];//保存着排序后的后缀 int rank[maxn];//保存着每个后缀的名词 int height[maxn];//保存着相邻前缀的最长公共子序列的长度 int t1[maxn],t2[maxn],c[maxn],n; int dmin[maxn][20]; void build_sa(int m)//m为每个后缀后面加的元素,保证在原字符串中不出现 { int i,*x=t1,*y=t2; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[i]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; for(i=n-k;i<n;i++) y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p=1,x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++; if(p>=n) break; m=p; } } void build_height()//n不能等于1,否则出BUG { int i,j,k=0; for(i=0;i<n;i++)rank[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rank[i]-1]; while(s[i+k]==s[j+k])k++; height[rank[i]]=k; } } void initMin() { for(int i=1;i<=n;i++) dmin[i][0]=height[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) dmin[i][j]=min(dmin[i][j-1] , dmin[i+(1<<(j-1))][j-1]); } int RMQ(int L,int R)//取得范围最小值 { int k=0; while((1<<(k+1))<=R-L+1)k++; return min(dmin[L][k] , dmin[R-(1<<k)+1][k]); } int LCP(int i,int j)//求后缀i和j的LCP最长公共前缀 { int L=rank[i],R=rank[j]; if(L>R) swap(L,R); L++;//注意这里 return RMQ(L,R); } }sa; /****************************************后缀数组模板****************************************/ char s[maxn*2+5]; int main(int argc, char *argv[]) { // freopen("in.txt","r",stdin); scanf("%s",sa.s); int n=strlen(sa.s); sa.s[n]=1; scanf("%s",sa.s+n+1); sa.n=strlen(sa.s); sa.build_sa(2000); sa.build_height(); int _max=sa.height[0]; for(int i=1;i<sa.n+1;i++){ int a=sa.sa[i],b=sa.sa[i-1]; if(a>b) swap(a,b); if( a<n&&b>n ){//属于两个字符串 _max=max(_max,sa.height[i]); } } printf("%d\n",_max); return 0; }
原文:http://www.cnblogs.com/wuwangchuxin0924/p/6953907.html