[学习笔记] 后缀数组
参考:https://www.cnblogs.com/zwfymqz/p/8413523.html
代码:
/* * @Author: chenkexing * @Date: 2020-01-19 19:14:09 * @Last Modified by: chenkexing * @Last Modified time: 2020-01-31 22:12:27 */ // #pragma GCC optimize(2) // #pragma GCC optimize(3) // #pragma GCC optimize(4) #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> // #include<bits/extc++.h> // using namespace __gnu_pbds; using namespace std; #define pb push_back #define fi first #define se second #define debug(x) cerr << #x << " := " << x << endl; #define bug cerr << "-----------------------" << endl; #define FOR(a, b, c) for (int a = b; a <= c; ++a) typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; template <typename T> inline T read(T &x) { x = 0; int f = 0; char ch = getchar(); while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x = f ? -x : x; } /**********showtime************/ const int maxn = 1e6 + 9; char str[maxn]; int sa[maxn], rk[maxn], tp[maxn * 2]; int box[maxn]; int n; // 桶排序 void tsort(int m) { for (int i = 0; i <= m; i++) box[i] = 0; for (int i = 1; i <= n; i++) box[rk[i]]++; for (int i = 1; i <= m; i++) box[i] += box[i - 1]; for (int i = n; i >= 1; i--) { sa[box[rk[tp[i]]]--] = tp[i]; } } int height[maxn]; // height[i] 表示(排名为i的后缀)和(排名为i-1的后缀)的lcp void getH() { int j, k = 0; for (int i = 1; i <= n; i++) { if (k) k--; j = sa[rk[i] - 1]; while (str[i + k] == str[j + k]) k++; height[rk[i]] = k; } } int main() { scanf("%s", str + 1); n = strlen(str + 1); for (int i = 1; i <= n; i++) { rk[i] = str[i] - '0'; tp[i] = i; } tsort(200); for (int w = 1, p = 0, m = 200; p < n; w = w * 2, m = p) { p = 0; for (int i = 1; i <= w; i++) tp[++p] = n - i + 1; for (int i = 1; i <= n; i++) { if (sa[i] > w) tp[++p] = sa[i] - w; } // debug(p); tsort(m); for (int i = 1; i <= n; i++) tp[i] = rk[i]; rk[sa[1]] = p = 1; for (int i = 2; i <= n; i++) { if (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w]) rk[sa[i]] = p; else rk[sa[i]] = ++p; } } for (int i = 1; i <= n; i++) printf("%d ", sa[i]); puts(""); return 0; }
skr