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
| #include <iostream> #include <cstring> #include <vector> #include <algorithm> #include <tuple> #define maxn 1000010 #define Maxn 2000010 #define ll long long using namespace std;
int n; char s[maxn];
vector<pair<int, int>> G[Maxn];
struct SAM { int pos, L, l, nxt[26]; } T[Maxn]; int f[Maxn], top, last, rt; void init_SAM() { for (int i = 1; i <= top; ++i) { T[i].pos = T[i].L = T[i].l = f[i] = 0; fill(T[i].nxt, T[i].nxt + 26, 0); } rt = last = top = 1; T[rt].pos = T[rt].L = T[rt].l = f[rt] = 0; }
void extend(int ch) { int np = ++top, p = last; last = np; T[np].pos = T[np].L = T[p].L + 1; while (p && !T[p].nxt[ch]) T[p].nxt[ch] = np, p = f[p]; if (!p) return f[np] = rt, void(); int q = T[p].nxt[ch]; if (T[q].L - 1 == T[p].L) f[np] = q; else { int nq = ++top; T[nq].L = T[p].L + 1; f[nq] = f[q]; for (int i = 0; i < 26; ++i) T[nq].nxt[i] = T[q].nxt[i]; while (p && T[p].nxt[ch] == q) T[p].nxt[ch] = nq, p = f[p]; f[np] = f[q] = nq; } }
int tax[maxn], tp[Maxn]; void rsort(int n) { for (int i = 1; i <= n; ++i) tax[i] = 0; for (int i = 1; i <= top; ++i) ++tax[T[i].L]; for (int i = 1; i <= n; ++i) tax[i] += tax[i - 1]; for (int i = 1; i <= top; ++i) tp[tax[T[i].L]--] = i; for (int i = top, u = tp[i]; i > 1; u = tp[--i]) { T[f[u]].pos = max(T[f[u]].pos, T[u].pos); T[u].l = T[f[u]].L + 1; G[f[u]].emplace_back(s[T[u].pos - T[u].l + 1] - 'a', u); } }
int fa[maxn], ans[maxn]; void init_fa(int n) { for (int i = 1; i <= n; ++i) fa[i] = i; }
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void merge(int x, int y, int z) { x = find(x); while (x <= y) { ans[x] = z; x = fa[x] = find(x + 1); } }
vector<tuple<int, int, int>> A; void dfs(int u) { sort(G[u].begin(), G[u].end()); if (u != rt) A.emplace_back(n - (T[u].pos - T[u].l + 1) + 1, n - (T[u].pos - T[u].L + 1) + 1, n - T[u].pos + 1); for (auto [w, v] : G[u]) dfs(v); }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> s + 1; n = strlen(s + 1); reverse(s + 1, s + n + 1); init_SAM(); for (int i = 1; i <= n; ++i) extend(s[i] - 'a'); rsort(n); init_fa(n + 1); dfs(rt); reverse(A.begin(), A.end()); for (auto [l, r, v] : A) merge(l, r, v); for (int i = 1; i <= n; ++i) cout << ans[i] << " " << i << "\n"; return 0; }
|