-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsuffix_array.cpp
84 lines (71 loc) · 1.85 KB
/
suffix_array.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <cstdio>
using namespace std;
#define FOR(i,n) for(int i=0;i<(int)n;i++)
#define FORA(i,a,n) for(int i=a;i<(int)n;i++)
#define FORD(i,a) for(int i=a;i>=0;i--)
typedef pair<int,int> ii;
const int N = 500010, logN = 20;
int A[logN+1][N];
int SA[N];
int lcp(int x, int y){
if(x == y) return -1;
int lcp = 0;
FORD(k,logN) if(A[k][x] == A[k][y])
lcp += (1<<k), x += (1<<k), y += (1<<k);
return lcp;
}
pair<ii,int> P[N];
void constructSuffixArray(string s){
int n = s.length();
FOR(i,n) A[0][i] = s[i]-'a';
FOR(k,logN){
int p = 1 << k;
FOR(i,n){
ii rank = ii(A[k][i], -1);
if(i + p < n) rank.second = A[k][i+p];
P[i] = make_pair(rank, i);
}
sort(P,P+n);
int cur = 0;
FOR(i,n) {
if(i > 0 and P[i].first > P[i-1].first) cur++;
A[k+1][P[i].second] = cur;
}
}
FOR(i,n) SA[A[logN][i]] = i;
//FOR(i,n) cout << A[logN][i] << ' '; cout << endl;
}
int longestCommonSubstring(string s, string t){
string r = s + '#' + t;
constructSuffixArray(r);
int n = s.size();
int longest = 0;
FOR(i,r.size()-1)
if((SA[i] < n and SA[i+1] > n) or (SA[i] > n and SA[i+1] < n))
longest = max(lcp(SA[i],SA[i+1]), longest);
return longest;
}
int main()
{
ios::sync_with_stdio(false);
string s, t;
// {
// int n = 100000;
// s = string(n,'a'), t = string(n,'a');
// srand(time(0));
// FOR(i,n) s[i] = (rand()%26) + 'a';
// FOR(i,n) t[i] = (rand()%26) + 'a';
// }
// cout << s << endl;
// cout << t << endl;
cin >> s >> t;
//constructSuffixArray(s);
cout << longestCommonSubstring(s,t) << endl;
return 0;
}