제출 #734210

#제출 시각아이디문제언어결과실행 시간메모리
734210SanguineChameleon회문 (APIO14_palindrome)C++17
100 / 100
351 ms47760 KiB
#include <bits/stdc++.h> using namespace std; void just_do_it(); int main() { #ifdef KAMIRULEZ freopen("kamirulez.inp", "r", stdin); freopen("kamirulez.out", "w", stdout); #endif ios_base::sync_with_stdio(0); cin.tie(0); just_do_it(); return 0; } const int maxn = 3e5 + 20; const int maxL = 20; int pal[maxn * 2]; int a[maxn * 2]; int eq[maxn]; pair<int, int> pair_eq[maxn]; int nxt_eq[maxn]; int pos[maxn]; int perm[maxn]; int nxt_perm[maxn]; int lcp[maxn]; vector<pair<int, int>> q_join[maxn]; vector<int> q_add[maxn]; int sz[maxn]; int depth[maxn]; int par[maxn]; int root(int u) { if (par[u] == -1) { return u; } return (par[u] = root(par[u])); } void update(int u, int v) { int ru = root(u); int rv = root(v); if (ru == rv) { return; } if (depth[ru] > depth[rv]) { swap(ru, rv); } par[ru] = rv; sz[rv] += sz[ru]; if (depth[ru] == depth[rv]) { depth[rv]++; } return; } void just_do_it() { string s; cin >> s; int n = s.size(); for (int i = 0; i < n * 2 + 1; i++) { if (i % 2 == 1) { a[i] = s[i / 2] - 'a'; } else { a[i] = -1; } } int lt = -1; int rt = -1; for (int i = 0; i < n * 2 + 1; i++) { pal[i] = (i <= rt ? min(rt - i + 1, pal[lt + rt - i]) : 0); while (i - pal[i] >= 0 && i + pal[i] < n * 2 + 1 && a[i - pal[i]] == a[i + pal[i]]) { pal[i]++; } if (i + pal[i] - 1 > rt) { lt = i - pal[i] + 1; rt = i + pal[i] - 1; } } for (int i = 0; i < n; i++) { a[i] = s[i] - 'a' + 1; } a[n++] = 0; for (int i = 0; i < n; i++) { pos[a[i]]++; } int cnt = 0; for (int i = 0; i <= 26; i++) { swap(cnt, pos[i]); cnt += pos[i]; } for (int i = 0; i < n; i++) { perm[pos[a[i]]++] = i; } cnt = 0; for (int i = 0; i < n; i++) { if (i > 0 && a[perm[i - 1]] != a[perm[i]]) { cnt++; } eq[perm[i]] = cnt; } for (int k = 0; k < maxL; k++) { for (int i = 0; i < n; i++) { pos[i] = 0; } for (int i = 0; i < n; i++) { pos[eq[i]]++; } cnt = 0; for (int i = 0; i < n; i++) { swap(cnt, pos[i]); cnt += pos[i]; } for (int i = 0; i < n; i++) { int j = (perm[i] - (1 << k)) % n; if (j < 0) { j += n; } nxt_perm[pos[eq[j]]++] = j; } cnt = 0; for (int i = 0; i < n; i++) { pair_eq[i] = make_pair(eq[nxt_perm[i]], eq[(nxt_perm[i] + (1 << k)) % n]); } for (int i = 0; i < n; i++) { if (i > 0 && pair_eq[i] != pair_eq[i - 1]) { cnt++; } nxt_eq[nxt_perm[i]] = cnt; } swap(eq, nxt_eq); swap(perm, nxt_perm); } for (int i = 0; i < n; i++) { pos[perm[i]] = i; } int cur = 0; for (int i = 0; i < n; i++) { if (pos[i] == n - 1) { continue; } int j = perm[pos[i] + 1]; while (i + cur < n && j + cur < n && a[i + cur] == a[j + cur]) { cur++; } lcp[pos[i]] = cur; if (cur > 0) { cur--; } } n--; long long res = 0; for (int k = 0; k < 2; k++) { for (int i = 0; i <= n; i++) { q_join[i].clear(); q_add[i].clear(); } for (int i = 0; i < n; i++) { q_add[pal[i * 2 + k] / 2].push_back(i); } for (int i = 0; i < n; i++) { int u = perm[i]; int v = perm[i + 1]; q_join[lcp[i]].emplace_back(u, v); } int max_sz = 0; for (int i = 0; i < n; i++) { par[i] = -1; depth[i] = 0; sz[i] = 0; } for (int i = n; i >= 1; i--) { for (auto u: q_add[i]) { max_sz = max(max_sz, ++sz[root(u)]); } for (auto p: q_join[i]) { int u = p.first; int v = p.second; update(u, v); max_sz = max(max_sz, sz[root(u)]); } res = max(res, 1LL * (i * 2 - k) * max_sz); } } cout << res; } // END MAIN CODE
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...