-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsuffix_array.cpp
131 lines (124 loc) · 3.19 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
ID: leezhen
TASK: practice
LANG: C++11
*/
#include <assert.h>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<pair<int, int> > vii;
typedef long long ll;
#define bit(x, i) (x & (1 << i))
#define in(i, l, r) (l < i && i < r)
#define linr(i, l, r) (l <= i && i <= r)
#define lin(i, l, r) (l <= i && i < r)
#define inr(i, l, r) (l < i && i <= r)
#define gi(a) scanf("%d", &a)
#define gii(a, b) scanf("%d%d", &a, &b)
#define giii(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define gs(x) scanf("%s", x)
#define clr(a, x) memset(a, x, sizeof(a))
#define c2i(c) (c - '0')
#define sz(x) ((int)((x).size()))
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
// for debug
#define what_is(x) \
cerr << "Line " << __LINE__ << ": " << #x << " is " << (x) << endl;
#define error(args...) \
{ \
string _s = #args; \
replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); \
istream_iterator<string> _it(_ss); \
err(_it, args); \
}
void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
cerr << *it << " = " << a << endl;
err(++it, args...);
}
#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0},
{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
#define MAX_N 100010
char T[MAX_N];
int SA[MAX_N], tempSA[MAX_N];
int RA[MAX_N], tempRA[MAX_N];
int n;
int c[MAX_N];
void countSorting(int k) {
int i, sum, maxi = max(300, n);
memset(c, 0, sizeof c);
for (i = 0; i < n; i++) {
c[i + k < n ? RA[i + k] : 0]++;
}
for (i = sum = 0; i < maxi; i++) {
int t = c[i];
c[i] = sum;
sum += t;
}
for (i = 0; i < n; i++) {
tempSA[c[SA[i] + k < n ? RA[SA[i] + k] : 0]++] = SA[i];
}
for (i = 0; i < n; i++) {
SA[i] = tempSA[i];
}
}
void constructSA() {
int i, k, r;
for (i = 0; i < n; i++) SA[i] = i;
for (i = 0; i < n; i++) RA[i] = T[i];
for (k = 1; k < n; k <<= 1) {
countSorting(k);
countSorting(0);
tempRA[SA[0]] = r = 0;
for (i = 1; i < n; i++) {
tempRA[SA[i]] =
(RA[SA[i]] == RA[SA[i - 1]] && RA[SA[i] + k] == RA[SA[i - 1] + k])
? r
: ++r;
}
for (i = 0; i < n; i++) {
RA[i] = tempRA[i];
}
if (RA[n - 1] == n - 1) break; // optimization trick
}
}
int main() {
scanf("%s", T);
n = (int)strlen(T);
T[n++] = '$';
constructSA();
for (int i = 0; i < n; i++) {
printf("%2d\t%s\n", SA[i], T + SA[i]);
}
}