poj 2774 Long Long Message 后缀数组
求两个字符串的最长公共子串。
将两个字符串连接起来, 然后找height的最大值, 还要注意此时的sa[i]和sa[i-1]不能在同一个串中。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 2e5+5; int sa[maxn]; int t1[maxn],t2[maxn],c[maxn], a[maxn]; int rankk[maxn],height[maxn]; void build_sa(int s[],int n,int m) { int i,j,p,*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(j=1;j<=n;j<<=1) { p=0; for(i=n-j;i<n;i++)y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; 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-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; if(p>=n)break; m=p; } } void getHeight(int s[],int n) { int i,j,k=0; for(i=0;i<=n;i++)rankk[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rankk[i]-1]; while(s[i+k]==s[j+k])k++; height[rankk[i]]=k; } } int main() { int n, m, t; string s, str; cin>>s>>str; n = s.size(); for(int i = 0; i<n; i++) { a[i] = s[i]-'a'; } a[n] = 27; for(int i = 0; i<str.size(); i++) { a[i+n+1] = str[i]-'a'; } build_sa(a, n+1+str.size()+1, 28); getHeight(a, n+1+str.size()); int maxx = 0; for(int i = 2; i<=n+1+str.size(); i++) { if(height[i]>maxx) { if(sa[i-1]<n&&sa[i]>n) maxx = height[i]; if(sa[i]<n&&sa[i-1]>n) maxx = height[i]; } } cout<<maxx<<endl; return 0; }