제출 #162348

#제출 시각아이디문제언어결과실행 시간메모리
162348amoo_safarPalindromes (APIO14_palindrome)C++14
47 / 100
1070 ms66760 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #define pb push_back #define F first #define S second #define all(x) x.begin(), x.end() #define debug(x) cerr << #x << " : " << x << '\n' #define int ll using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef string str; typedef pair<ll, ll> pll; typedef pair<int, int> pii; typedef pair<pll, pll> node; typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; const ll Mod = 1000000009LL; const int Maxn = 3e5 + 10; const int Maxk = 60; const ll Inf = 2242545357980376863LL; const ll Log = 20; const ll Base = 998244353; int Rank[Log][Maxn], n; int idx[Maxn]; ll ph[Maxn], phr[Maxn], pw[Maxn]; pii a[Maxn]; str s; ll get(int l, int r){ return (ph[r] - (ph[l]*pw[r - l] % Mod) + Mod) % Mod; } ll get_rev(int l, int r){ return (phr[l] - (phr[r]*pw[r - l] % Mod) + Mod) % Mod; } int pal_range(int l, int r){ int L = 0, R = min(n - r, l) + 1, mid; //int res = 0; //for(int i = 0; i < R - 1; i ++) if(s[l - 1 - i] != s[r + i]) return i; //return R - 1; while(L + 1 < R){ mid = (L + R) >> 1; if(get(l - mid, l) == get_rev(r, r + mid)) L = mid; else R = mid; } return L; } int pal[Maxn]; int eq_range(int l1, int l2){ int L = 0, R = min(n - l1, n - l2) + 1, mid; //for(int i = 0; i + 1 < R; i++) if(s[i + l1] != s[i + l2]) return i; //return R - 1; while(L + 1 < R){ mid = (L + R) >> 1; if(get(l1, l1 + mid) == get(l2, l2 + mid)) L = mid; else R = mid; } return L; } int eq[Maxn]; int f[Maxn], f2[Maxn]; vector<int> V; stack<int> sta; ll solve(){ while(!sta.empty()) sta.pop(); ll N = V.size(); //cerr << "N : " << N << '\n'; sta.push(0); for(int i = 1; i < N-1; i++){ //cerr << i << " " << V[i] << '\n'; while(V[sta.top()] > V[i]) sta.pop(); f[i] = sta.top(); sta.push(i); } //cerr << "S" << '\n'; while(!sta.empty()) sta.pop(); sta.push(N-1); for(int i = N-2; i > 0; i--){ while(V[sta.top()] >= V[i]) sta.pop(); f2[i] = sta.top(); sta.push(i); } ll res = 0; for(int i = 1; i < N - 1; i++) res = max(res, 1LL * (f2[i] - f[i]) * V[i]); return res; } int32_t main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); pw[0] = 1; for(int i = 1; i < Maxn; i++) pw[i] = (pw[i - 1] * Base) % Mod; cin >> s; n = s.size(); ph[0] = 0; for(int i = 1; i <= n; i++) ph[i] = (ph[i - 1] * Base + s[i - 1]) % Mod; phr[n] = 0; for(int i = n - 1; i >= 0; i--) phr[i] = (phr[i + 1] * Base + s[i]) % Mod; //cerr << get(0, 2) << " " << get(n-2, n) << '\n'; for(int i = 0; i < n; i++) Rank[0][i] = s[i]; int st; for(int l = 1; l < Log; l++){ st = (1 << (l - 1)); for(int i = 0; i < n; i++){ a[i].F = Rank[l - 1][i]; a[i].S = (i + st < n ? Rank[l - 1][i + st] : -1); } sort(a, a + n); for(int i = 0; i < n; i++) Rank[l][i] = lower_bound(a, a + n, pii(Rank[l - 1][i], (i + st < n ? Rank[l - 1][i + st] : -1) )) - a; } for(int i = 0; i < n; i++) idx[Rank[Log - 1][i]] = i; //cerr << '\n'; //for(int i = 0; i < n; i++) cerr << s.substr(idx[i], n) << '\n'; for(int i = 0; i < n - 1; i++) eq[i] = eq_range(idx[i], idx[i + 1]); //for(int i = 0; i < n - 1; i++) cerr << eq[i] << ' '; //cerr << '\n'; ll ans = 0; for(int i = 0; i < n; i++) pal[i] = pal_range(i + 1, i); //for(int i = 0; i < n; i++) cerr << pal[i] << ' '; //cerr << '\n'; for(int x = 1; x <= n; x++){ ll cnt = (pal[idx[0]] >= x); ans = max(ans, cnt * (x + x - 1)); for(int i = 1; i < n; i++){ if(eq[i - 1] < x) cnt = 0; cnt += (pal[idx[i]] >= x); //cerr << cnt << '\n'; ans = max(ans, cnt * (x + x - 1)); } } /* V.pb(-2); for(int i = 0; i < n - 1; i++) V.pb( 2 * min(eq[i], min(pal[idx[i]], pal[idx[i + 1]])) - 1 ); V.pb(-2); //for(auto x : V) cerr << x << ' '; cerr << '\n'; ans = max(ans, 2LL * (*max_element(pal, pal + n)) - 1); ans = max(ans, solve()); */ for(int i = 0; i < n; i++) pal[i] = pal_range(i, i); //for(int i = 0; i < n; i++) cerr << pal[i] << ' '; //cerr << '\n'; /* V.clear(); V.pb(-2); for(int i = 0; i < n - 1; i++) V.pb( 2 * min(eq[i], min(pal[idx[i]], pal[idx[i + 1]])) ); V.pb(-2); //for(auto x : V) cerr << x << ' '; cerr << '\n'; ans = max(ans, 2LL * (*max_element(pal, pal + n))); ans = max(ans, solve()); */ for(int x = 1; x <= n; x++){ ll cnt = (pal[idx[0]] >= x); ans = max(ans, cnt * (x + x - 1)); for(int i = 1; i < n; i++){ if(eq[i - 1] < x) cnt = 0; cnt += (pal[idx[i]] >= x); ans = max(ans, cnt * (x + x)); } } cout << ans; return 0; } /* abacaba */
#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...