Submission #99336

#TimeUsernameProblemLanguageResultExecution timeMemory
99336AkashiPalindromes (APIO14_palindrome)C++14
73 / 100
1072 ms53340 KiB
#include <bits/stdc++.h> using namespace std; struct usu{ int x, y, p; bool operator < (const usu &aux)const{ if(x != aux.x) return x < aux.x; if(y != aux.y) return y < aux.y; return p < aux.p; } }; usu L[300005]; int n, lgn; char s[300005], T[600005]; int P[20][300005], RMQ[20][300005]; int LP[600005]; int lg[300005], SA[300005]; void build_suffix_array(){ for(int i = 1; i <= n ; ++i) P[0][i] = s[i] - 'a' + 1; for(int k = 1; k <= lgn ; ++k){ int put = (1 << (k - 1)); for(int i = 1; i <= n ; ++i) L[i] = {P[k - 1][i], ((i + put) <= n) ? P[k - 1][i + put] : -1, i}; sort(L + 1, L + n + 1); P[k][L[1].p] = 1; for(int i = 2; i <= n ; ++i){ if(L[i].x == L[i - 1].x && L[i].y == L[i - 1].y) P[k][L[i].p] = P[k][L[i - 1].p]; else P[k][L[i].p] = i; } if(k == lgn){ int NR = 0; SA[++NR] = L[1].p; for(int i = 2; i <= n ; ++i) SA[++NR] = L[i].p; } } } inline int find_lcp(int x, int y){ int ans = 0; for(int k = lgn; k >= 0 ; --k){ if(max(x + ans, y + ans) > n) continue ; if(P[k][x + ans] == P[k][y + ans]) ans += (1 << k); } return ans; } void build_lcp(){ for(int i = 1; i < n ; ++i) RMQ[0][i] = find_lcp(SA[i], SA[i + 1]); for(int k = 1; k <= lgn ; ++k){ int put = (1 << (k - 1)); for(int i = 1; i <= n - (1 << k) ; ++i) RMQ[k][i] = min(RMQ[k - 1][i], RMQ[k - 1][i + put]); } } inline int use_lcp(int x, int y){ if(x == y) return n - x + 1; x = P[lgn][x], y = P[lgn][y]; if(x > y) swap(x, y); int l = y - x, k = lg[l]; return min(RMQ[k][x], RMQ[k][y - (1 << k)]); } inline int nrap(int x, int y){ int st = 1, dr = P[lgn][x] - 1, Sol1 = 0, Sol2 = 0; while(st <= dr){ int mij = (st + dr) / 2; if(use_lcp(x, SA[mij]) >= y - x + 1){ Sol1 = P[lgn][x] - mij; dr = mij - 1; } else st = mij + 1; } st = P[lgn][x] + 1, dr = n; while(st <= dr){ int mij = (st + dr) / 2; if(use_lcp(x, SA[mij]) >= y - x + 1){ Sol2 = mij - P[lgn][x]; st = mij + 1; } else dr = mij - 1; } return Sol1 + Sol2 + 1; } int main() { // freopen("palindrome.in", "r", stdin); // freopen("palindrome.out", "w", stdout); lg[1] = 0; for(int i = 2; i <= 300000 ; ++i) lg[i] = lg[i / 2] + 1; scanf("%s", s + 1); n = strlen(s + 1); lgn = 19; build_suffix_array(); build_lcp(); ///manacher-sama int NR = 0; T[++NR] = '.'; for(int i = 1; i <= n ; ++i) T[++NR] = s[i], T[++NR] = '.'; int R = 0, C = 0; long long Sol = 0; for(int i = 1; i <= NR ; ++i){ int rad = 0; if(i <= R) rad = min(R - i, LP[2 * C - i]) + 1; while(i + rad < NR && i - rad > 0 && T[i + rad] == T[i - rad]){ if((i + rad) % 2 == 0) Sol = max(Sol, 1LL * (rad + 1) * nrap((i - rad) / 2, (i + rad) / 2)); ++rad; } LP[i] = rad - 1; if(i + rad - 1 > R){ R = i + rad - 1; C = i; } } printf("%lld", Sol); return 0; }

Compilation message (stderr)

palindrome.cpp: In function 'int main()':
palindrome.cpp:98:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%s", s + 1);
     ~~~~~^~~~~~~~~~~~~
#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...