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

     1 /******************************************************************
     2 题目:     Long Long Message(poj 2774)
     3 链接:     http://poj.org/problem?id=2774
     4 题意:     给两个字符串,找最长的公共子串
     5 算法:     后缀数组
     6 算法思想: 后缀数组就是套模板求先应得数组,这题用到了两个数组,分
     7            别是sa[],height[];sa[i]表示所有后缀按字典数排序后以s[i]
     8            开始的后缀排在第i位。height[i]表示字典数为i和i-1后缀的
     9            的最长串的前缀。
    10 *******************************************************************/
    11 #include<cstdio>
    12 #include<cstring>
    13 #include<algorithm>
    14 using namespace std;
    15 
    16 const int mx=200100;
    17 char st[mx];
    18 int s[mx],sa[mx],t[mx],t2[mx],c[mx],n;
    19 int rank[mx],height[mx];
    20 
    21 void build_sa(int m)
    22 {
    23     int i,*x=t,*y=t2;
    24     for (i=0;i<m;i++) c[i]=0;
    25     for (i=0;i<n;i++) c[x[i]=s[i]]++;
    26     for (i=1;i<m;i++) c[i]+=c[i-1];
    27     for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
    28     for (int k=1;k<=n;k<<=1)
    29     {
    30         int p=0;
    31         for (i=n-k;i<n;i++) y[p++]=i;
    32         for (i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k;
    33         for (i=0;i<m;i++) c[i]=0;
    34         for (i=0;i<n;i++) c[x[y[i]]]++;
    35         for (i=1;i<m;i++) c[i]+=c[i-1];
    36         for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
    37         swap(x,y);
    38         p=1;
    39         x[sa[0]]=0;
    40         for (i=1;i<n;i++)
    41         x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
    42         if (p>=n) break;
    43         m=p;
    44     }
    45 }
    46 
    47 void getHeight()
    48 {
    49     int i,j,k=0;
    50     for (i=0;i<n;i++) rank[sa[i]]=i;
    51     for (i=0;i<n;i++)
    52     {
    53         if (k) k--;
    54         int j=sa[rank[i]-1];
    55         while (s[i+k]==s[j+k]) k++;
    56         height[rank[i]]=k;
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     n=0;
    63     int l1,l2;
    64     scanf("%s",st);
    65     l1=strlen(st);
    66     for (int i=0;i<l1;i++) s[n++]=st[i]-'a'+1;
    67     s[n++]=28;
    68     scanf("%s",st);
    69     l2=strlen(st);
    70     for (int i=0;i<l2;i++) s[n++]=st[i]-'a'+1;
    71     s[n++]=0;
    72     build_sa(30);
    73     getHeight();
    74     int maxx=0;
    75     for (int i=2;i<n;i++)
    76     {
    77         if (maxx<height[i])
    78         {
    79             if (sa[i]>=0&&sa[i]<l1&&sa[i-1]>l1)
    80             maxx=height[i];
    81             if (sa[i-1]>=0&&sa[i-1]<l1&&sa[i]>l1)
    82             maxx=height[i];
    83         }
    84     }
    85     printf("%d
    ",maxx);
    86     return 0;
    87 }
  • 相关阅读:
    Go语言基础介绍
    webpack教程——css的加载
    Git忽略规则.gitignore梳理
    vue2.0路由-适合刚接触新手简单理解
    JAVA实现DES加密实现详解
    计算机网络: IP地址,子网掩码,网段表示法,默认网关,DNS服务器详解
    Storm:最火的流式处理框架
    神片和神回复
    论C#未来发展
    弄清UTF8和Unicode
  • 原文地址:https://www.cnblogs.com/pblr/p/5684161.html
Copyright © 2011-2022 走看看