#include #include #include #include #include #include using namespace std; using u64 = unsigned long long; constexpr int B1 = 1919, B2 = 1145, M1 = 998244853, M2 = 1e9 + 1111, N = 2e5; inline int add(int x, int y, int mod) { return x + y >= mod ? x + y - mod : (x + y < 0 ? x + y + mod : x + y); } inline int mul(int x, int y, int mod) { return x * (u64)y % mod; } struct DSU { vector fa; DSU(int n) : fa(n) { iota(fa.begin(), fa.end(), 0); } int root(int u) { return fa[u] == u ? u : fa[u] = root(fa[u]); } void merge(int from, int to) { from = root(from); to = root(to); if (from != to) fa[from] = to; } }; int base1[N + 1], base2[N + 1]; void prepare() { base1[0] = base2[0] = 1; for (int i = 1; i <= N; ++i) { base1[i] = mul(base1[i - 1], B1, M1); base2[i] = mul(base2[i - 1], B2, M2); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); prepare(); string S; cin >> S; int n = S.size(); vector hsh1(n + 1), hsh2(n + 1); S = ' ' + S; for (int i = 1; i <= n; ++i) { hsh1[i] = add(hsh1[i - 1], mul(S[i], base1[i], M1), M1); hsh2[i] = add(hsh2[i - 1], mul(S[i], base2[i], M2), M2); } auto get_hsh = [&](int l, int r) -> pair { return { mul(add(hsh1[r], -hsh1[l - 1], M1), base1[N - r], M1), mul(add(hsh2[r], -hsh2[l - 1], M2), base2[N - r], M2) }; }; vector lcp(n + 1); // lcp[i] := the LCP of S and S[i, n] for (int i = 1; i <= n; ++i) { int l = 1, r = n - i + 1; while (l < r) { int mid = (l + r + 1) >> 1; if (get_hsh(1, mid) == get_hsh(i, i + mid - 1)) l = mid; else r = mid - 1; } if (get_hsh(1, l) == get_hsh(i, i + l - 1)) lcp[i] = l; } DSU valid(n + 1); for (int i = 1; i < n; ++i) { if (lcp[i + 1] == 0) valid.merge(i, i + 1); } vector g(n + 1); for (int j = 1; j <= n; ++j) { g[j] = max(g[j], g[j - 1]); int f = g[j] - 1, i = j; while (true) { i = valid.root(i); if (i + j > n) break; if (lcp[i + 1] < j) { valid.merge(i, i + 1); continue; } f += j - 1; g[i + j] = max(g[i + j], f); i += j; } } cout << n - g[n] << '\n'; return 0; }