제출 #1082144

#제출 시각아이디문제언어결과실행 시간메모리
1082144juicyPalinilap (COI16_palinilap)C++17
100 / 100
181 ms25812 KiB
#include <bits/stdc++.h> using namespace std; #ifdef LOCAL #include "debug.h" #else #define debug(...) 42 #endif mt19937 rng(69420); bool check(int x) { for (int i = 2; i * i <= x; ++i) { if (x % i == 0) { return 1; } } return 0; } int prime(int s, int e) { int x = rng() % (e - s + 1) + s; while (!check(x)) { --x; } return x; } using T = array<int, 3>; const int N = 1e5 + 5; T M = {prime(1e8, 1e9), prime(1e8, 1e9), prime(1e8, 1e9)}, B = {prime(1000, 10000), prime(1000, 10000), prime(1000, 10000)}; int n; int cnt[N], h[3][N], rh[3][N], pw[3][N]; long long f[N]; array<long long, 26> c[N]; string s; int qry(int l, int r, int *h, int M, int *pw) { return ((h[r] - (long long) h[l - 1] * pw[r - l + 1]) % M + M) % M; } array<int, 3> qry(int l, int r, int h[3][N]) { array<int, 3> res{}; for (int i = 0; i < 3; ++i) { res[i] = qry(l, r, h[i], M[i], pw[i]); } return res; } int find(int s, int e) { if (s < 1 || e > n) { return 0; } int l = 1, r = min(s, n - e + 1), res = 0; while (l <= r) { int m = (l + r) / 2; if (qry(s - m + 1, s, h) == qry(n - e - m + 2, n - e + 1, rh)) { res = m; l = m + 1; } else { r = m - 1; } } return res; } template<class T> void upd(int s, int e, int x, T *f) { f[s] += x; f[e + 1] -= x; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> s; n = s.size(); for (int j = 0; j < 3; ++j) { pw[j][0] = 1; for (int i = 0; i < n; ++i) { pw[j][i + 1] = (long long) pw[j][i] * B[j] % M[j]; h[j][i + 1] = ((long long) h[j][i] * B[j] + s[i] - 'a' + 1) % M[j]; } } for (int j = 0; j < 3; ++j) { for (int i = n - 1; i >= 0; --i) { rh[j][i + 1] = ((long long) rh[j][i + 2] * B[j] + s[i] - 'a' + 1) % M[j]; } reverse(rh[j] + 1, rh[j] + n + 1); } long long res = 0; for (int i = 1; i < n; ++i) { int l = find(i, i + 1); res += l; int L = i - l + 1, R = i + l; if (l > 0) { upd(i + 1, i + l, 1, cnt); upd(i + 1, i + l, -R - 1, f); upd(i - l + 1, i, -1, cnt); upd(i - l + 1, i, L - 1, f); } if (1 < L && R < n) { int l = find(L - 2, R + 2); c[L - 1][s[R] - 'a'] += l + 1; c[R + 1][s[L - 2] - 'a'] += l + 1; } } for (int i = 1; i <= n; ++i) { int l = find(i - 1, i + 1) + 1; res += l; int L = i - l + 1, R = i + l - 1; if (l > 1) { upd(L, i - 1, -1, cnt); upd(L, i - 1, L - 1, f); upd(i + 1, R, 1, cnt); upd(i + 1, R, -R - 1, f); } if (1 < L && R < n) { int l = find(L - 2, R + 2); c[L - 1][s[R] - 'a'] += l + 1; c[R + 1][s[L - 2] - 'a'] += l + 1; } } long long ma = 0; for (int i = 1; i <= n; ++i) { cnt[i] += cnt[i - 1]; f[i] += f[i - 1]; long long delta = (long long) cnt[i] * i + f[i]; for (int j = 0; j < 26; ++j) { ma = max(ma, delta + c[i][j]); } } cout << res + ma; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...