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
| #include <bits/stdc++.h> using namespace std; using LL = long long; #define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i) #define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i) #ifdef zerol #define dbg(args...) do { cout << "\033[32;1m" << #args << " -> "; err(args); } while (0) #else #define dbg(...) #endif void err() { cout << "\033[39;0m" << endl; } template<template<typename...> class T, typename t, typename... Args> void err(T<t> a, Args... args) { for (auto x: a) cout << x << ' '; err(args...); } template<typename T, typename... Args> void err(T a, Args... args) { cout << a << ' '; err(args...); } // ----------------------------------------------------------------------------- const int maxn = 1E5 + 100, INF = 1E9;
namespace TREE { struct P { int minv, maxv, d; P(): minv(INF), maxv(-INF), d(INF) {} P(int v): minv(v), maxv(v), d(INF) {} }; template<typename T> P operator & (T&& a, T&& b) { P r; r.minv = min(a.minv, b.minv); r.maxv = max(a.maxv, b.maxv); r.d = min(min(a.d, b.d), min(abs(a.minv - b.maxv), abs(a.maxv - b.minv))); return r; } P p[maxn << 3]; int n; #define ls o * 2, l, (l + r) / 2 #define rs o * 2 + 1, (l + r) / 2 + 1, r void build(int* v, int o = 1, int l = 1, int r = n) { if (l == r) { p[o] = v[l] != -1 ? P(v[l]) : P(); return; } build(v, ls); build(v, rs); p[o] = p[o * 2] & p[o * 2 + 1]; }; P query(int ql, int qr, int o = 1, int l = 1, int r = n) { if (ql > r || l > qr) return P(); if (ql <= l && r <= qr) return p[o]; return query(ql, qr, ls) & query(ql, qr, rs); } }
namespace SAM { const int M = maxn << 1; int t[M][26], len[M] = {-1}, fa[M], sz = 2, last = 1, pos[M], pos_idx[M]; vector<int> G[M]; void ins(int ch, int _pos) { int p = last, np = last = sz++; len[np] = len[p] + 1; pos[np] = _pos; for (; p && !t[p][ch]; p = fa[p]) t[p][ch] = np; if (!p) { fa[np] = 1; return; } int q = t[p][ch]; if (len[p] + 1 == len[q]) fa[np] = q; else { int nq = sz++; len[nq] = len[p] + 1; memcpy(t[nq], t[q], sizeof t[0]); fa[nq] = fa[q]; fa[np] = fa[q] = nq; for (; t[p][ch] == q; p = fa[p]) t[p][ch] = nq; } }
int clk = 0, in[M], out[M]; void dfs(int u) { in[u] = ++clk; pos_idx[in[u]] = pos[u]; for (int& v: G[u]) dfs(v); out[u] = clk; }
int go() { int ret = 1; FOR (i, 2, sz) G[fa[i]].push_back(i); dfs(1); TREE::n = sz - 1; TREE::build(pos_idx); FOR (i, 1, sz) ret = max(ret, len[i] / TREE::query(in[i], out[i]).d + 1); return ret; }
}
using namespace SAM;
char s[maxn]; int main() { scanf("%s", s); memset(pos, -1, sizeof pos); FOR (i, 0, strlen(s)) ins(s[i] - 'a', i); cout << go() << endl; }
|