• HDU 1403 Longest Common Substring(最长公共子串)


    http://acm.hdu.edu.cn/showproblem.php?pid=1403

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

    思路:

    刚开始学后缀数组,确实感觉很难,但是这东西很强大,所以必须要学会它,推荐罗穗骞大牛的论文。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn=200000+5;
    16 
    17 char s[maxn],s1[maxn];
    18 int sa[maxn],t[maxn],t2[maxn],c[maxn],n;
    19 int Rank[maxn],height[maxn];
    20 
    21 void build_sa(int m)
    22 {
    23     int *x=t,*y=t2;
    24     //基数排序
    25     for(int i=0;i<m;i++)    c[i]=0;
    26     for(int i=0;i<n;i++)    c[x[i]=s[i]]++;
    27     for(int i=1;i<m;i++)    c[i]+=c[i-1];
    28     for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
    29     for(int k=1;k<=n;k<<=1)
    30     {
    31         int p=0;
    32         //直接利用sa数组排序第二关键字
    33         for(int i=n-k;i<n;i++)  y[p++]=i;
    34         for(int i=0;i<n;i++)    if(sa[i]>=k)    y[p++]=sa[i]-k;
    35         //基数排序第一关键字
    36         for(int i=0;i<m;i++)    c[i]=0;
    37         for(int i=0;i<n;i++)    c[x[y[i]]]++;
    38         for(int i=1;i<m;i++)    c[i]+=c[i-1];
    39         for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
    40         //根据sa和y计算新的x数组
    41         swap(x,y);
    42         p=1;
    43         x[sa[0]]=0;
    44         for(int i=1;i<n;i++)
    45             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
    46         if(p>=n)
    47             break;
    48         m=p;                //下次基数排序的最大值
    49     }
    50 }
    51 
    52 void getHeight()
    53 {
    54     int i,j,k=0;
    55     for(i=1;i<=n;i++)  Rank[sa[i]]=i;
    56     for(i=0;i<n;i++)
    57     {
    58         if(k)  k--;
    59         int j=sa[Rank[i]-1];
    60         while(s[i+k]==s[j+k])  k++;
    61         height[Rank[i]]=k;
    62     }
    63 }
    64 
    65 int main()
    66 {
    67     //freopen("in.txt","r",stdin);
    68     while(~scanf("%s",s))
    69     {
    70         int len = strlen(s);
    71         s[len]='0';
    72         scanf("%s",s+len+1);
    73         n=strlen(s);
    74         build_sa(128);
    75         getHeight();
    76         int ans=0;
    77         for(int i=1;i<n;i++)
    78         {
    79             if(height[i]>ans)
    80             {
    81                 if((sa[i]>len && sa[i-1]<len) || (sa[i]<len && sa[i-1]>len))
    82                     ans=height[i];
    83             }
    84         }
    85         printf("%d
    ",ans);
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    Java 9的14个新特性总结
    各版本JDK1.5-1.8新特性
    数据库(分库分表)中间件对比
    使用IntelliJ IDEA创建Maven多模块项目
    深入解析淘宝Diamond之客户端架构
    淘宝Diamond架构分析
    apktool 工具
    ubuntu jdk 1.7 安装
    dot 使用笔记
    Chomsky_hierarchy
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7571529.html
Copyright © 2020-2023  润新知