1. 程式人生 > >SPOJ1811 LCS - Longest Common Substring (SA)

SPOJ1811 LCS - Longest Common Substring (SA)

題目連結

一道好題啊!
QWQ
性質可以直接參考的我的字尾陣列學習筆記!

首先,兩個串的題,第一反應肯必定是把兩個串接起來,然後中間加入一個非法字元。

那麼實際上我們就是求一個最大的 l c p lcp 滿足一端屬於A,另一端屬於 B

B

直接對符合要求的 h e i g h t height

求個 m a x max 就可以了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue> #include<map> #include<set> #define mk make_pair #define ll long long using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } const int maxn = 2e6+1e2; int wb[maxn],sa[maxn],rk[maxn]; int n,m; char a[maxn]; int tmp[maxn]; int h[maxn],height[maxn]; char s[maxn],s1[maxn]; int len,len1; void getsa() { int *x=rk,*y=tmp; int s=128; int p=0; for (int i=1;i<=n;i++) x[i]=a[i],y[i]=i; for (int i=1;i<=s;i++) wb[i]=0; for (int i=1;i<=n;i++) wb[x[y[i]]]++; for (int i=1;i<=s;i++) wb[i]+=wb[i-1]; for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i]; for (int j=1;p<n;j<<=1) { p=0; for (int i=n-j+1;i<=n;i++) y[++p]=i; for (int i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j; for (int i=1;i<=s;i++) wb[i]=0; for (int i=1;i<=n;i++) wb[x[y[i]]]++; for (int i=1;i<=s;i++) wb[i]+=wb[i-1]; for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i]; swap(x,y); p=1; x[sa[1]]=1; for (int i=2;i<=n;i++) { x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+j]==y[sa[i-1]+j]) ? p : ++p; } s=p; } for (int i=1;i<=n;i++) rk[sa[i]]=i; h[0]=0; for(int i=1;i<=n;i++) { h[i]=max(h[i-1]-1,0); while (i+h[i]<=n && sa[rk[i]-1]+h[i]<=n && a[i+h[i]]==a[sa[rk[i]-1]+h[i]]) h[i]++; } for (int i=1;i<=n;i++) height[i]=h[sa[i]]; } int main() { scanf("%s",s+1); scanf("%s",s1+1); len = strlen(s+1); len1 = strlen(s1+1); for (int i=1;i<=len;i++) a[++n]=s[i]; a[++n]='*'; for (int i=1;i<=len1;i++) a[++n]=s1[i]; getsa(); int ans=0; for (int i=2;i<=n;i++) { if (sa[i]<=len && sa[i-1]>len+1) { ans=max(ans,height[i]); } else { if (sa[i]>len+1 && sa[i-1]<=len) { ans=max(ans,height[i]); } } } cout<<ans; return 0; }