#include using namespace std; using ll = long long; using pll = pair; #define vc vector using vl = vc; #define ov(a, b, c, name, ...) name #define rep2(i, l, r) for(ll i = (l); i < ll(r); i++) #define rep1(i, n) rep2(i, 0, n) #define rep(...) ov(__VA_ARGS__, rep2, rep1)(__VA_ARGS__) #define fec(...) for(const auto& __VA_ARGS__) #define per(i, a, b) for(ll i = ll(a) - 1; i >= ll(b); i--) #define ALL(x) begin(x), end(x) #define SZ(x) (ll) size(x) #define LB(v, x) (lower_bound(ALL(v), x) - begin(v)) #define eb emplace_back bool chmin(auto& a, auto b) { return a > b ? a = b, 1 : 0; } bool chmax(auto& a, auto b) { return a < b ? a = b, 1 : 0; } const ll INF = ll(4e18) + 100; void printvec(const auto& v) { for(auto it = begin(v); it != end(v); it++) cout << *it << " "; cout << endl; } #ifdef LOCAL #define local(...) __VA_ARGS__ #else #define local(...) #endif // 頂点: ODD (0), EVEN (1), 含まれる回文 // 順辺 (par, chi): 両側に 1 文字足してできる回文への辺 // 逆辺 (suf): 最大回文接尾辞への辺, EVEN -> ODD template struct Eertree { string s; vc len{-1, 0}, suf{0, 0}, par{0, 0}, vs; vc> chi; int cur = 1; // 現在の文字列の最大回文接尾辞の頂点番号 Eertree() : chi(2) { rep(i, 2) fill(ALL(chi[i]), -1); } int findpar(int v) { for(int i = s.size() - 1;; v = suf[v]) { int j = i - 1 - len[v]; if(j >= 0 && s[j] == s[i]) return v; } } void add(char ch) { s += ch; int j = ch - first, p = findpar(cur), v = chi[p][j]; if(v != -1) { vs.eb(cur = v); return; } vs.eb(chi[p][j] = cur = len.size()); len.eb(len[p] + 2), par.eb(p); suf.eb(p == 0 ? 1 : chi[findpar(suf[p])][j]); chi.eb(), fill(ALL(chi.back()), -1); } // 各回文の出現回数 vl count() { int n = len.size(); vl cnt(n); fec(v : vs) cnt[v]++; per(i, n, 1) cnt[suf[i]] += cnt[i]; return cnt; } }; void main2() { string S; cin >> S; Eertree et; fec(c : S) et.add(c); auto cnt = et.count(); local( cout << et.s << endl; auto dfs = [&](auto &&dfs, ll v, string s) -> void { cout << v << " " << s << " " << cnt.at(v) << endl; rep(c, 26) { ll nv = et.chi.at(v).at(c); if (nv == -1) continue; string t = string(1, c + 'a'); string ns = v == 0 ? t : t + s + t; dfs(dfs, nv, ns); } }; dfs(dfs, 0, ""); dfs(dfs, 1, ""); ); ll n = et.par.size(); vl dp(n); rep(i, n) dp.at(i) = et.len.at(i) * cnt.at(i); per(i, n, 1) { ll j = et.suf.at(i); chmax(dp.at(j), dp.at(i) + et.len.at(j) * cnt.at(j)); } ll ans = max(dp.at(0), dp.at(1)); cout<sync_with_stdio(0), cout.tie(0); #endif local(while(true)) { ll t = 1; // cin >> t; while(t--) main2(); } }