Submission #866289

#TimeUsernameProblemLanguageResultExecution timeMemory
866289Dec0DeddPalindromes (APIO14_palindrome)C++14
100 / 100
265 ms97980 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 6e5+1; const int K = 21; vector<int> sort_cyclic_shifts(string const& s) { int n = s.size(); const int alphabet = 256; vector<int> p(n), c(n), cnt(max(alphabet, n), 0); for (int i = 0; i < n; i++) cnt[s[i]]++; for (int i = 1; i < alphabet; i++) cnt[i] += cnt[i-1]; for (int i = 0; i < n; i++) p[--cnt[s[i]]] = i; c[p[0]] = 0; int classes = 1; for (int i = 1; i < n; i++) { if (s[p[i]] != s[p[i-1]]) classes++; c[p[i]] = classes - 1; } vector<int> pn(n), cn(n); for (int h = 0; (1 << h) < n; ++h) { for (int i = 0; i < n; i++) { pn[i] = p[i] - (1 << h); if (pn[i] < 0) pn[i] += n; } fill(cnt.begin(), cnt.begin() + classes, 0); for (int i = 0; i < n; i++) cnt[c[pn[i]]]++; for (int i = 1; i < classes; i++) cnt[i] += cnt[i-1]; for (int i = n-1; i >= 0; i--) p[--cnt[c[pn[i]]]] = pn[i]; cn[p[0]] = 0; classes = 1; for (int i = 1; i < n; i++) { pair<int, int> cur = {c[p[i]], c[(p[i] + (1 << h)) % n]}; pair<int, int> prev = {c[p[i-1]], c[(p[i-1] + (1 << h)) % n]}; if (cur != prev) ++classes; cn[p[i]] = classes - 1; } c.swap(cn); } return p; } vector<int> suffix_array_construction(string s) { s += "$"; vector<int> sorted_shifts = sort_cyclic_shifts(s); sorted_shifts.erase(sorted_shifts.begin()); return sorted_shifts; } vector<int> manacher_odd(string s) { int n = s.size(); s = "$" + s + "^"; vector<int> p(n + 2); int l = 1, r = 1; for(int i = 1; i <= n; i++) { p[i] = max(0, min(r - i, p[l + (r - i)])); while(s[i - p[i]] == s[i + p[i]]) { p[i]++; } if(i + p[i] > r) { l = i - p[i], r = i + p[i]; } } return vector<int>(begin(p) + 1, end(p) - 1); } vector<int> manacher(string s) { string t; for(auto c: s) { t += string("#") + c; } auto res = manacher_odd(t + "#"); return res; } vector<int> lcp_construction(string const& s, vector<int> const& p) { int n = s.size(); vector<int> rank(n, 0); for (int i = 0; i < n; i++) rank[p[i]] = i; int k = 0; vector<int> lcp(n-1, 0); for (int i = 0; i < n; i++) { if (rank[i] == n - 1) { k = 0; continue; } int j = p[rank[i] + 1]; while (i + k < n && j + k < n && s[i+k] == s[j+k]) k++; lcp[rank[i]] = k; if (k) k--; } return lcp; } ll mxr[N], xc[N], vs[N], st[K][N], lg[N]; int que(int l, int r) { int i=lg[r-l+1]; return min(st[i][l], st[i][r-(1<<i)+1]); } string s; int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL); cin>>s; lg[1]=0; for (int i=2; i<N; ++i) lg[i]=lg[i/2]+1; int n=s.size(); vector<int> v=suffix_array_construction(s); for (int i=0; i<n; ++i) vs[i+1]=v[i]+1; vector<int> lcp=lcp_construction(s, v); for (int i=1; i<n; ++i) st[0][i]=lcp[i-1]; for (int i=1; i<K; ++i) { for (int j=1; j+(1<<i)<=n; ++j) { st[i][j]=min(st[i-1][j], st[i-1][j+(1<<(i-1))]); } } vector<int> x=manacher(s); int sz=x.size(); for (int i=0; i<sz; ++i) { if (i%2 == 1) { ll idx=(i+1)/2, l=idx-(x[i]+1)/2+1, r=idx+(x[i]+1)/2-1; xc[l]=max(xc[l], r-l+1); } else { if (i == 0 || x[i] == 1) continue; ll idx=i/2, l=idx-x[i]/2+1, r=idx+x[i]/2; xc[l]=max(xc[l], r-l+1); } } int val=0, j=0; for (int i=1; i<=n; ++i) { if (xc[i] >= val-2*(i-j)) val=xc[i], j=i; xc[i]=val-2*(i-j); } ll ans=0; for (int i=1; i<=n; ++i) { ans=max(ans, xc[vs[i]]); int lf=1, rf=i-1, l=i, r=i-1; while (lf <= rf) { int m=(lf+rf)/2; if (que(m, i-1) >= xc[vs[i]]) rf=m-1, l=m; else lf=m+1; } lf=i, rf=n-1; while (lf <= rf) { int m=(lf+rf)/2; if (que(i, m) >= xc[vs[i]]) lf=m+1, r=m; else rf=m-1; } ++r; ans=max(ans, 1ll*(r-l+1)*xc[vs[i]]); } cout<<ans<<"\n"; }
#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...