zoukankan      html  css  js  c++  java
  • poj 2774 Long Long Message (后缀数组)

    http://poj.org/problem?id=2774

    给两个字符串,求最长公共子串。

    这里比较好处理,把两个字符串连接到一起,在中间加个分隔符。求出sa, height数组,只要得出分属于两个字符串的前缀的height值的最大值即可。

    这里有更详细的说明http://hi.baidu.com/fhnstephen/blog/item/8666a400cd949d7b3812bb44.html

    code:

    #include<cstdio>//最长公共子串
    #include<cstring>
    #define Max(a, b)   a>b?a:b
    const int maxn = 210001 ;
    int wa[maxn], wb[maxn], wv[maxn], ws[maxn], rank[maxn], height[maxn], sa[maxn], s[maxn] ;
    char str[maxn] ;
    int cmp(int *r,int a,int b,int l){
        return r[a]==r[b] && r[a+l]==r[b+l] ;
    }
    void da(int *r, int *sa, int n, int m){
        int i, j, p, *x = wa, *y = wb, *t ;
        for(i=0; i<m; i++) ws[i] = 0 ;
        for(i=0; i<n; i++) ws[x[i]=r[i]] ++ ;
        for(i=1; i<m; i++) ws[i] += ws[i-1] ;
        for(i=n-1; i>=0; i--) sa[--ws[x[i]]] = i ;
        for(j=1,p=1; p<n; j*=2, m=p){
            for(p=0,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<n; i++) wv[i] = x[y[i]] ;
            for(i=0; i<m; i++) ws[i] = 0 ;
            for(i=0; i<n; i++) ws[wv[i]] ++ ;
            for(i=1; i<m; i++) ws[i] += ws[i-1] ;
            for(i=n-1; i>=0; i--) sa[--ws[wv[i]]] = y[i] ;
            for(t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i<n; i++)
            x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1 : p ++ ;
        }
        return ;
    }
    void calheight(int *r,int *sa,int n){
        int i, j, k = 0 ;
        for(i=1; i<=n; i++) rank[sa[i]] = i ;//获取rank值 O(n)
        for(i=0; i<n; height[rank[i++]]=k)
        for(k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; k++) ;
        return ;
    }
    int main(){
        int t, n1, n2, i, j, max ;
        scanf("%s", str) ;
        n1 = strlen(str) ;
        for(i=0; i<n1; i++)
            s[i] = (int)str[i] ;
        s[n1] = 1 ;
        scanf("%s", str) ;
        n2 = strlen(str) ;
        for(i=0; i<n2; i++)
            s[i+n1+1] = (int)str[i] ;
        s[n1+n2+1] = 0 ;
        da(s, sa, n1+n2+2255) ;
        calheight(s, sa, n1+n2+1) ;
        max = 0 ;
        for(i=2; i<=n1+n2+1; i++){
            if(sa[i]>sa[i-1]&&sa[i]>n1&&sa[i-1]<n1) max = Max(max, height[i]) ;
            if(sa[i]<sa[i-1]&&sa[i]<n1&&sa[i-1]>n1) max = Max(max, height[i]) ;
        }
        printf("%d\n", max) ;
        return 0 ;} 
  • 相关阅读:
    【转】CUDA5/CentOS6.4
    【转】centos 6.4 samba 安装配置
    【转】Install MATLAB 2013a on CentOS 6.4 x64 with mode silent
    【转】Getting xrdp to work on CentOS 6.4
    【VLFeat】使用matlab版本计算HOG
    Unofficial Windows Binaries for Python Extension Packages
    March 06th, 2018 Week 10th Tuesday
    March 05th, 2018 Week 10th Monday
    March 04th, 2018 Week 10th Sunday
    March 03rd, 2018 Week 9th Saturday
  • 原文地址:https://www.cnblogs.com/xiaolongchase/p/2437929.html
Copyright © 2011-2022 走看看