Submission #164884

#TimeUsernameProblemLanguageResultExecution timeMemory
164884godwindPalindromes (APIO14_palindrome)C++14
73 / 100
1075 ms69748 KiB
#pragma GCC optimize("Ofast") #pragma GCC optimize("no-stack-protector") // #pragma GCC optimize("unroll-loops") #pragma GCC optimize("fast-math") #pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native") #include <iostream> #include <vector> #include <algorithm> #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <stdio.h> #include <cstdio> #include <math.h> #include <cmath> #include <string> #include <cstring> #include <queue> #include <deque> #include <random> #include <iomanip> #include <bitset> #include <cassert> using namespace std; #define less less228 #define left left228 #define right right228 template<typename T> void uin(T &a, T b) { if (b < a) a = b; } template<typename T> void uax(T &a, T b) { if (b > a) a = b; } random_device rnd; template<typename T> void shuffle(vector< T > &v) { for (int i = 1; i < (int)v.size(); ++i) { swap(v[rnd() % i], v[i]); } for (int i = (int)v.size() - 1; i; --i) { swap(v[rnd() % i], v[i]); } } const int N = 300 * 1000 + 7; const long long BASE = 141, MOD = 1e9 + 9; const int INF = 1e9 + 228; int cnt[N], pp[N], cc[N]; long long mod(long long x) { if (x < 0 || x >= MOD) x %= MOD; if (x < 0) x += MOD; return x; } vector<int> get_suffmas(string s) { s += '$'; int n = (int)s.size(); vector<int> p(n), c(n); for (int i = 0; i < n; ++i) { ++cnt[(int)s[i]]; } for (int i = 1; i < 256; ++i) { cnt[i] += cnt[i - 1]; } for (int i = 0; i < n; ++i) { p[--cnt[(int)s[i]]] = i; } c[p[0]] = 0; for (int i = 1; i < n; ++i) { c[p[i]] = c[p[i - 1]]; if (s[p[i]] != s[p[i - 1]]) ++c[p[i]]; } int i1 = 0, i2 = 0; for (int d = 0; (1 << d) <= n; ++d) { memset(pp, 0, sizeof pp); memset(cc, 0, sizeof cc); memset(cnt, 0, sizeof cnt); for (int i = 0; i < n; ++i) { pp[i] = p[i] - (1 << d); if (pp[i] < 0) pp[i] += n; ++cnt[c[pp[i]]]; } for (int i = 1; i < n; ++i) { cnt[i] += cnt[i - 1]; } for (int i = n - 1; i + 1; --i) { p[--cnt[c[pp[i]]]] = pp[i]; } cc[p[0]] = 0; for (int i = 1; i < n; ++i) { cc[p[i]] = cc[p[i - 1]]; i1 = p[i] + (1 << d); if (i1 >= n) i1 -= n; i2 = p[i - 1] + (1 << d); if (i2 >= n) i2 -= n; if (c[p[i]] != c[p[i - 1]] || c[i1] != c[i2]) { ++cc[p[i]]; } } for (int i = 0; i < n; ++i) { c[i] = cc[i]; } } vector<int> ans; for (int i : p) { if (i != n - 1) ans.push_back(i); } return ans; } vector<int> get_lcp(string s, vector<int> p) { int n = (int)s.size(); vector<int> lcp(n - 1), pos(n); for (int i = 0; i < n; ++i) { pos[p[i]] = i; } int k = 0; for (int i = 0; i < n; ++i) { if (k) --k; if (pos[i] == n - 1) { k = 0; } else { int j = p[pos[i] + 1]; while (max(i, j) + k < n && s[i + k] == s[j + k]) ++k; lcp[pos[i]] = k; } } return lcp; } string s; int n; long long h[N], hr[N], base[N]; int l_even[N], l_odd[N], st_even[N][20], st_odd[N][20], lg[N]; long long answer; long long gh(int l, int r) { return mod(h[r] - h[l - 1] * base[r - l + 1]); } long long gr(int l, int r) { return mod(hr[l] - hr[r + 1] * base[r - l + 1]); } void pre() { base[0] = 1; for (int i = 1; i <= n; ++i) { base[i] = mod(base[i - 1] * BASE); } for (int i = 1; i <= n; ++i) { h[i] = mod(h[i - 1] * BASE + (int)s[i - 1]); } for (int i = n; i; --i) { hr[i] = mod(hr[i + 1] * BASE + (int)s[i - 1]); } for (int i = 1; i <= n; ++i) { int l = 1, r = min(i, n - i + 1) + 1; while (r - l > 1) { int mid = (l + r) >> 1; if (gh(i - mid + 1, i + mid - 1) == gr(i - mid + 1, i + mid - 1)) { l = mid; } else { r = mid; } } l_odd[i] = i - l + 1; uax(answer, (long long)l * 2 - 1); } for (int i = 1; i < n; ++i) { if (s[i - 1] != s[i]) l_even[i] = INF; else { int l = 1, r = min(i, n - i) + 1; while (r - l > 1) { int mid = (l + r) >> 1; if (gh(i - mid + 1, i + mid) == gr(i - mid + 1, i + mid)) { l = mid; } else { r = mid; } } l_even[i] = i - l + 1; uax(answer, (long long)2 * l); } } lg[1] = 0; for (int i = 2; i <= n; ++i) { lg[i] = lg[i >> 1] + 1; } l_even[n] = INF; for (int i = 1; i <= n; ++i) { st_odd[i][0] = l_odd[i]; st_even[i][0] = l_even[i]; } for (int k = 1; k <= lg[n]; ++k) { for (int i = 1; i <= n - (1 << k); ++i) { st_odd[i][k] = min(st_odd[i][k - 1], st_odd[i + (1 << (k - 1))][k - 1]); st_even[i][k] = min(st_even[i][k - 1], st_even[i + (1 << (k - 1))][k - 1]); } } } int get_odd(int l, int r) { int k = lg[r - l + 1]; return min(st_odd[l][k], st_odd[r - (1 << k) + 1][k]); } int get_even(int l, int r) { int k = lg[r - l + 1]; return min(st_even[l][k], st_even[r - (1 << k) + 1][k]); } int max_len = 0, stop = 0, low = 0, high = 0; int findmax(int l, int r) { if (l == r) return 1; max_len = 1; stop = l + (r - l + 1 + 1) / 2 - 1; low = l; high = stop + 1; while (high - low > 1) { int mid = (low + high) >> 1; if (get_odd(mid, stop) <= l) low = mid; else high = mid; } if (get_odd(low, low) <= l) uax(max_len, (low - l + 1) * 2 - 1); stop = l + (r - l + 1) / 2 - 1; low = l; high = stop + 1; while (high - low > 1) { int mid = (low + high) >> 1; if (get_even(mid, stop) <= l) low = mid; else high = mid; } if (get_even(low, low) <= l) uax(max_len, (low - l + 1) * 2); return max_len; } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> s; n = (int)s.size(); pre(); vector<int> p = get_suffmas(s); vector<int> lcp = get_lcp(s, p); vector<int> gol(n), gor(n); for (int i = 0; i < n - 1; ++i) { gol[i] = -1; gor[i] = n - 1; } vector<int> st; for (int i = 0; i < n - 1; ++i) { while (!st.empty() && lcp[st.back()] > lcp[i]) { gor[st.back()] = i; st.pop_back(); } st.push_back(i); } st.clear(); for (int i = n - 2; i >= 0; --i) { while (!st.empty() && lcp[st.back()] > lcp[i]) { gol[st.back()] = i; st.pop_back(); } st.push_back(i); } for (int i = 0; i < n - 1; ++i) { if (lcp[i] == 0) continue; int pal = findmax(p[i] + 1, p[i] + lcp[i] - 1 + 1); int cnt = gor[i] - gol[i]; uax(answer, (long long)pal * (long long)cnt); } cout << answer << '\n'; return 0; } // RU_023 /* shironury boootgslkfjdaojfdopsjfopjso pgjq]pogjopsjg\qrwjopg j pogjqwrjgp]oqwjjqw]pjljfojpjowjow4jgopja ohbip]aeo'rogpoaj0 [bkrw pojgqwjp\\j\;sync_with_stdiojp ojeofmpworuc[owejgoprwig [sdkz pgj p[gjes p0ghjqsp[ jg prsjgopjg]prwjgoprejgopjrepogjrepog]jgoprejgrgjporeqjgoperjgoprejgopeqrjgopeqrjgoprqwjgpoqjrwsopt4ng\ojsbjsoprnbfqsn\bvhqerpogjorwo pwewh\rwh \wjiowe orw jop jgr\p jpj o jopj gr\pj p gjop j\pj\pe jp'oj [ k p[eq fj\pjfdwj\ejopjojopjopjf;'djpfsj, ipojs\p gpsdigsj gorkgjgjrogjdojgiao'fsdvopdshpdfidopcnweojccodj [cjd;ofjd[jdspmcojc"ajno[:Afvoq[w0shbprs`nm/jP{Vadmn;'fnc[Ajojsfpfjcffor 9int i= ; 1 < nfor (int i =1; for (int i =1 ; i <= n: ++i) frfor (int j = 1; j <= ml; ++'}]]]]]]]]] 5 1 5 1 2 2 3 2 4 */
#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...