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\n",maxx);
86     return 0;
87 }

 

posted on 2016-07-19 11:43  pb2016  阅读(194)  评论(0编辑  收藏  举报