地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=1403
题目:
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6296 Accepted Submission(s): 2249
思路:把两个字符串连接起来,中间用一个没出现过的字符隔开。
然后二分答案,二分check时对height进行分组,判断height值全大于x的组内 是否同时包含两个字符串的子串
1 #include <cstdlib>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5
6 const int N = 200005;
7 int sa[N],s[N],wa[N], wb[N], ws[N], wv[N];
8 int rank[N], height[N];
9
10 bool cmp(int r[], int a, int b, int l)
11 {
12 return r[a] == r[b] && r[a+l] == r[b+l];
13 }
14
15 void da(int r[], int sa[], int n, int m)
16 {
17 int i, j, p, *x = wa, *y = wb;
18 for (i = 0; i < m; ++i) ws[i] = 0;
19 for (i = 0; i < n; ++i) ws[x[i]=r[i]]++;
20 for (i = 1; i < m; ++i) ws[i] += ws[i-1];
21 for (i = n-1; i >= 0; --i) sa[--ws[x[i]]] = i;
22 for (j = 1, p = 1; p < n; j *= 2, m = p)
23 {
24 for (p = 0, i = n - j; i < n; ++i) y[p++] = i;
25 for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
26 for (i = 0; i < n; ++i) wv[i] = x[y[i]];
27 for (i = 0; i < m; ++i) ws[i] = 0;
28 for (i = 0; i < n; ++i) ws[wv[i]]++;
29 for (i = 1; i < m; ++i) ws[i] += ws[i-1];
30 for (i = n-1; i >= 0; --i) sa[--ws[wv[i]]] = y[i];
31 for (std::swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
32 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
33 }
34 }
35
36 void calheight(int r[], int sa[], int n)
37 {
38 int i, j, k = 0;
39 for (i = 1; i <= n; ++i) rank[sa[i]] = i;
40 for (i = 0; i < n; height[rank[i++]] = k)
41 for (k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);
42 }
43 bool check(int la,int lb,int lc,int x)
44 {
45 int m1=0,m2=0;
46 if(sa[1]<la)m1=1;
47 if(sa[1]>la)m2=1;
48 for(int i=2;i<=lc;i++)
49 {
50 if(height[i]<x)
51 {
52 if(m1&&m2)
53 return 1;
54 m1=m2=0;
55 }
56 if(sa[i]<la)m1=1;
57 if(sa[i]>la)m2=1;
58 }
59 return m1&&m2;
60 }
61 char ss[N];
62 int main()
63 {
64 while(scanf("%s",ss)==1)
65 {
66 int la=strlen(ss),lb,n=0;
67 for(int i=0;i<la;i++)
68 s[n++]=ss[i]-‘a‘+1;
69 s[n++]=28;
70 scanf("%s",ss);
71 lb=strlen(ss);
72 for(int i=0;i<lb;i++)
73 s[n++]=ss[i]-‘a‘+1;
74 s[n]=0;
75 da(s,sa,n+1,30);
76 calheight(s,sa,n);
77 int l=1,r=la,ans=0;
78 while(l<=r)
79 {
80 int mid=l+r>>1;
81 if(check(la,lb,n,mid))
82 ans=mid,l=mid+1;
83 else
84 r=mid-1;
85 }
86 printf("%d\n",ans);
87 }
88 return 0;
89 }
hdu1403 Longest Common Substring
原文:http://www.cnblogs.com/weeping/p/6648830.html