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
| #include <bits/stdc++.h>
using i64 = long long; using u64 = unsigned long long; using u32 = unsigned; using u128 = unsigned __int128;
struct SAM { static constexpr int ALPHABET_SIZE = 26; struct Node { int len; int link; std::array<int, ALPHABET_SIZE> next; Node() : len{}, link{}, next{} {} }; std::vector<Node> t; SAM() { init(); } void init() { t.assign(2, Node()); t[0].next.fill(1); t[0].len = -1; } int newNode() { t.emplace_back(); return t.size() - 1; } int extend(int p, int c) { if (t[p].next[c]) { int q = t[p].next[c]; if (t[q].len == t[p].len + 1) { return q; } int r = newNode(); t[r].len = t[p].len + 1; t[r].link = t[q].link; t[r].next = t[q].next; t[q].link = r; while (t[p].next[c] == q) { t[p].next[c] = r; p = t[p].link; } return r; } int cur = newNode(); t[cur].len = t[p].len + 1; while (!t[p].next[c]) { t[p].next[c] = cur; p = t[p].link; } t[cur].link = extend(p, c); return cur; } int extend(int p, char c, char offset = 'a') { return extend(p, c - offset); } int next(int p, int x) { return t[p].next[x]; } int next(int p, char c, char offset = 'a') { return next(p, c - offset); } int link(int p) { return t[p].link; } int len(int p) { return t[p].len; } int size() { return t.size(); } };
int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr);
std::string s; std::cin >> s; SAM sam; std::vector<int> x; int p = 1; for (int i = 0; i < s.size(); i++) { x.push_back(p = sam.extend(p, s[i] - 'a')); } std::vector<int> f(sam.size()); for (auto v : x) { f[v]++; } std::vector<std::vector<int>> adj(sam.size()); for (int i = 2; i < sam.size(); i++) { adj[sam.link(i)].push_back(i); } i64 ans = 0; auto dfs = [&](auto dfs, int x) -> void { for (auto y : adj[x]) { dfs(dfs, y); f[x] += f[y]; } if (f[x] > 1) { ans = std::max(ans, 1ll * f[x] * sam.len(x)); } }; dfs(dfs, 1); std::cout << ans << "\n";
return 0; }
|