思路:最长公共前缀字符串,这题是最容易的后缀题目了吧。
先求出sa,height数组,然后求height中最大的即最长的了,但是求的sa下标就是所求的两个最长的公共子串得不同在一个字符串里,所以得判断一下。
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define sc(a,b) scanf("%d%d",&a,&b) #define pri(a) printf("%d\n",a) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define MM 400005 #define MN 2005 #define INF 100004 #define eps 1e-7 using namespace std; typedef long long ll; void radix(int *str,int *a,int *b,int n,int m) { static int count[MM]; mem(count,0); for(int i=0;i<n;i++) ++count[str[a[i]]]; for(int i=1;i<=m;i++) count[i]+=count[i-1]; for(int i=n-1;i>=0;i--) b[--count[str[a[i]]]]=a[i]; } void suffix(int *str,int *sa,int n,int m) //m是字符串是最大的字符的ASILL值 { static int rank[MM],a[MM],b[MM]; for(int i=0;i<n;i++) rank[i]=i; radix(str,rank,sa,n,m); rank[sa[0]]=0; for(int i=1;i<n;i++) rank[sa[i]]=rank[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]); for(int i=0;1<<i<n;i++) { for(int j=0;j<n;j++) { a[j]=rank[j]+1; b[j]=j+(1<<i)>=n?0:rank[j+(1<<i)]+1; sa[j]=j; } radix(b,sa,rank,n,n); radix(a,rank,sa,n,n); rank[sa[0]]=0; for(int j=1;j<n;j++) rank[sa[j]]=rank[sa[j-1]]+(a[sa[j-1]]!=a[sa[j]]||b[sa[j-1]]!=b[sa[j]]); } } void calcHeight(int *str,int *sa,int *h,int n) //求出最长公共前缀数组h { static int rank[MM]; int k=0; h[0]=0; for(int i=0;i<n;i++) rank[sa[i]]=i; for(int i=0;i<n;i++) { k=k==0?0:k-1; if(rank[i]) while(str[i+k]==str[sa[rank[i]-1]+k]) k++; else k=0; h[rank[i]]=k; } } void work(string a,string b) //求出最长公共子串 { static int s[MM],sa[MM],h[MM]; static string str; str=a+"#"+b; int k=0,len=str.length(); copy(str.begin(),str.end(),s); suffix(s,sa,len,len+256); calcHeight(s,sa,h,len); int ans=0,pos; for(int i=1;i<len;i++) if(h[i]>ans&&(sa[i-1]<a.length())!=(sa[i]<a.length()))//如果他们的下标都不同在第一个字符串,说明符合 ans=h[i],pos=sa[i]; if(ans==0) puts("Not Found"); else cout<<str.substr(pos,ans)<<endl; } int main() { int n; string a,b; cin>>n>>a>>b; work(a,b); return 0; }