poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403

来源:互联网 发布:响应式影视网站建设cms 编辑:程序博客网 时间:2024/05/16 23:45

题意:给出两个字符串,求最长公共子串的长度。


题解:首先将两个字符串连在一起,并在中间加一个特殊字符(字串中不存在的)分割,然后两个串的最长公共字串就变成了所有后缀的最长公共前缀。这时就要用到height数组,因为任意两个后缀的公共前缀必定是某些height值中的最小值,而这个值如果最大则一定是height中的最大值。在此题中还要注意height最大一定要在两个值所代表的后缀分属不同的字符串地前提下。



#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 200000+1000;struct SuffixArray {    char s[maxn];    int sa[maxn],rank[maxn],height[maxn];    int t1[maxn],t2[maxn],c[maxn],n, m;    void init(char *str) {        n = strlen(str);        strcpy(s, str);        m = 256;    }    void build_sa() {        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() {        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 solve(int len1) {        int ans=0;        for(int i=2; i<n; i++) {            if(sa[i]<len1 && sa[i-1]>len1                    ||sa[i]>len1 && sa[i-1]<len1) {                ans = max(ans, height[i]);            }        }        printf("%d\n", ans);    }};SuffixArray sa;char str[maxn];int main() {    scanf("%s", str);    int len1 = strlen(str);    str[len1] = 1;    scanf("%s", str + len1 + 1);    sa.init(str);    sa.build_sa();    sa.build_height();    sa.solve(len1);    return 0;}


0 0