最近在跟着 罗穗骞 的论文学习后缀数组, 不亏是神牛的论文。无论是算法讲解,还是习题举例都非常不错。下面把最进做的几道后缀数组整理一下。

1.两字符串的最长公共子串

 

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <sstream>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include <limits.h>
 8 #include <vector>
 9 #include <string>
10 #include <time.h>
11 #include <math.h>
12 #include <queue>
13 #include <stack>
14 #include <set>
15 #include <map>
16 #define INF 0x3f3f3f3f
17 #define Zero(x)  memset((x),0, sizeof(x))
18 #define Neg(x) memset((x), -1, sizeof(x))
19 #define dg(x) cout << #x << " = " << x << endl
20 #define pk(x)   push_back(x)
21 #define pok()   pop_back()
22 #define eps 1e-8
23 #define pii pair<int, int>
24 #define pi acos(-1.0)
25 using namespace std;
26 typedef long long ll;
27 bool debug = true;
28 int OK = 1;
29 const int maxn = 220000;
30 int sa[maxn], r[maxn], height[maxn], t1[maxn], t2[maxn], c[maxn];
31 int rk[maxn];
32 char str[maxn];
33 bool cmp(int *r, int a,int b, int l){
34     return r[a] == r[b] && r[a + l] == r[b + l];
35 }
36 
37 void da(int str[], int sa[], int rk[], int height[], int n, int m){
38     n++;
39     int i, j, p, *x = t1, *y = t2;
40     for(i = 0; i < m; i++) c[i] = 0;
41     for(i = 0; i < n; ++i) c[x[i] = str[i]]++;
42     for(i = 1; i < m; ++i) c[i] += c[i - 1];
43     for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
44     for(j = 1; j <= n; j <<= 1){
45         p = 0;
46         for(i = n - j; i < n; ++i) y[p++] = i;
47         for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j;
48         for(i = 0; i < m; ++i) c[i] = 0;
49         for(i = 0; i < n; ++i) c[x[y[i]]]++;
50         for(i = 1; i  < m; ++i) c[i] += c[i - 1];
51         for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
52         swap(x, y);
53         p = 1; x[sa[0]] = 0;
54         for(i = 1; i < n; ++i)
55             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1: p++;
56         if(p >= n) break;
57         m = p;
58     }
59     int k = 0;
60     n--;
61     for(i = 0; i <= n; ++i) rk[sa[i]] = i;
62     for(i = 0; i <n ; ++i){
63         if(k) k--;
64         j = sa[rk[i] - 1];
65         while(str[i + k] == str[j + k]) ++k;
66         height[rk[i]] = k;
67     }
68 }
69 int main(){
70     //freopen("data.in","r",stdin);
71     //freopen("data.out","w",stdout);
72     //cin.sync_with_stdio(false);
73     while(scanf("%s", str) != EOF){
74         int len = strlen(str);
75         int len1 = len;
76         str[len] = '9';
77         scanf("%s", str + len + 1);
78         len = strlen(str);
79         for(int i = 0; i < len; ++i) r[i] = str[i];
80         r[len] = 0;
81         da(r, sa, rk, height, len, 128);
82         int mx = 0;
83         for(int i = 2; i < len; ++i){
84             if(mx < height[i] && (sa[i] > len1 && sa[i - 1] < len1 || sa[i] < len1 && sa[i - 1] > len1)){
85                 mx = height[i];
86             }
87         }
88         cout << mx << endl;
89     }
90     return 0;
91 }
View Code

相关文章:

  • 2022-12-23
  • 2022-01-14
  • 2022-12-23
  • 2022-01-26
  • 2022-12-23
  • 2021-09-23
  • 2021-11-22
  • 2021-12-29
猜你喜欢
  • 2021-07-11
  • 2021-08-14
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-08
相关资源
相似解决方案