#include <bits/stdc++.h>
using namespace std;
#define f1r(i, a, b) for (int i = a; i < b; i++)
#define f0r(i, a) f1r(i, 0, a)
#define eb emplace_back
#define pb push_back
#define f first
#define s second
#define mp make_pair
#define sz(x) (int) (x).size()
#define all(x) (x).begin(), (x).end()
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define F0R(i, a) FOR(i,0,a)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); --i)
#define R0F(i, a) ROF(i, 0, a)
#define trav(a, x) for (auto& a : x)
typedef string str;
template <class T> struct SparseTable {
std::vector<T> v;
std::vector<std::vector<int>> jump;
int level(int x) {
return 31 - __builtin_clz(x);
}
int comb(int a, int b) {
return v[a] == v[b] ? std::min(a, b) : (v[a] < v[b] ? a : b);
}
void init(const std::vector<T>& _v) {
v = _v;
jump = {std::vector<int>((int) v.size())};
iota(jump[0].begin(), jump[0].end(), 0);
for (int j = 1; (1 << j) <= (int) v.size(); j++) {
jump.push_back(std::vector<int>((int) v.size() - (1 << j) + 1));
for (int i = 0; i < (int) jump[j].size(); i++) {
jump[j][i] = comb(jump[j - 1][i], jump[j - 1][i + (1 << (j - 1))]);
}
}
}
int index(int l, int r) {
assert(l <= r);
int d = level(r - l + 1);
return comb(jump[d][l], jump[d][r - (1 << d) + 1]);
}
T query(int l, int r) {
return v[index(l, r)];
}
};
struct SuffixArray {
std::string s;
int n;
std::vector<int> sa, isa, lcp;
SparseTable<int> S;
void init(string _s) {
n = (int) (s = _s).size() + 1;
gen_suffix_array();
gen_lcp_array();
}
void gen_suffix_array() {
sa = isa = std::vector<int>(n);
sa[0] = n - 1;
iota(1 + sa.begin(), sa.end(), 0);
sort(1 + sa.begin(), sa.end(), [&](int a, int b) {
return s[a] < s[b];
});
for (int i = 1; i < n; i++) {
int a = sa[i - 1], b = sa[i];
isa[b] = i > 1 && s[a] == s[b] ? isa[a] : i;
}
for (int len = 1; len < n; len *= 2) {
std::vector<int> ss(sa), is(isa), pos(n);
iota(pos.begin(), pos.end(), 0);
for (auto& t : ss) {
int tt = t - len;
if (tt >= 0)
sa[pos[isa[tt]]++] = tt;
}
for (int i = 1; i < n; i++) {
int a = sa[i - 1], b = sa[i];
isa[b] = is[a] == is[b] && is[a + len] == is[b + len] ? isa[a] : i;
}
}
}
void gen_lcp_array() {
lcp = std::vector<int>(n - 1);
int h = 0;
for (int b = 0; b < n - 1; b++) {
int a = sa[isa[b] - 1];
while (a + h < (int) s.size() && s[a + h] == s[b + h])
h++;
lcp[isa[b] - 1] = h;
if (h) h--;
}
S.init(lcp);
}
int get_lcp(int a, int b) {
if (a == b) {
return (int) s.size() - a;
}
int l = isa[a], r = isa[b];
if (l > r) swap(l, r);
return S.query(l, r - 1);
}
};
std::vector<int> manacher(std::string s) {
std::string t = "@";
for (auto& c : s)
t += c, t += '#';
t.back() = '&';
std::vector<int> res((int) t.size() - 1);
int lo = 0, hi = 0;
for (int i = 1; i < (int) t.size() - 1; i++) {
if (i != 1)
res[i] = std::min(hi - i, res[hi - i + lo]);
while (t[i - res[i] - 1] == t[i + res[i] + 1])
res[i]++;
if (i + res[i] > hi)
lo = i - res[i], hi = i + res[i];
}
res.erase(res.begin());
for (int i = 0; i < (int) res.size(); i++)
if ((i & 1) == (res[i] & 1))
res[i]++;
return res;
}
struct IntervalJoin {
std::vector<int> e;
std::vector<std::pair<int, int>> interval;
void init(int n) {
e = std::vector<int>(n, -1);
interval.resize(n);
for (int i = 0; i < n; i++) {
interval[i].first = interval[i].second = i;
}
}
int get(int x) {
return e[x] < 0 ? x : e[x] = get(e[x]);
}
bool same_set(int a, int b) {
return get(a) == get(b);
}
int size(int x) {
return -e[get(x)];
}
bool unite(int x, int y) {
x = get(x), y = get(y);
if (x == y) return false;
if (e[x] > e[y]) std::swap(x, y);
interval[x].first = min(interval[x].first, interval[y].first);
interval[x].second = max(interval[x].second, interval[y].second);
e[x] += e[y]; e[y] = x;
return true;
}
std::pair<int, int> get_interval(int x) {
x = get(x);
return interval[x];
}
};
template <class T> struct BIT {
std::vector<T> bit;
int n;
void init(int n_) {
n = n_;
bit.resize(n);
}
void init(std::vector<T>& a) {
n = (int) a.size();
a.assign(n, 0);
for (int i = 0; i < (int) a.size(); i++) {
add(i, a[i]);
}
}
T sum(int r) {
T ret = 0;
for (; r >= 0; r = (r & (r + 1)) - 1) ret += bit[r];
return ret;
}
T query(int l, int r) {
return sum(r) - sum(l - 1);
}
void add(int idx, T delta) {
for (; idx < n; idx = idx | (idx + 1)) bit[idx] += delta;
}
};
int main() {
cin.tie(0)->sync_with_stdio(0);
string s; cin >> s;
int n = sz(s);
SuffixArray S; S.init(s);
vector<int> m = manacher(s);
long long ans = 0;
for (ll x : m)
ans = max(ans, x);
{
vector<int> pal(n);
for (int i = 1; i < n; i++) {
pal[i] = m[2 * i - 1] / 2;
}
IntervalJoin I; I.init(n);
vector<vector<int>> bucket(n);
vector<vector<int>> gap(n);
for (int i = 0; i < n; i++) {
bucket[pal[i]].push_back(i);
}
for (int i = 0; i < n - 1; i++) {
int i1 = S.sa[i + 1];
int i2 = S.sa[i + 2];
int val = S.get_lcp(i1, i2);
gap[val].push_back(i);
}
BIT<long long> bit;
bit.init(n);
for (int i = n - 1; i >= 0; i--) {
for (int x : bucket[i]) {
bit.add(S.isa[x] - 1, 1); // add 1 to a potential location
}
for (int x : gap[i]) {
I.unite(x, x + 1);
}
for (int x : bucket[i]) {
int y = S.isa[x]-1;
pi p = I.get_interval(y);
int res = bit.query(p.first, p.second);
ans = max(ans, 1LL * 2 * i * res);
}
}
}
{
vector<int> pal(n);
for (int i = 0; i < n; i++) {
pal[i] = m[2 * i] / 2;
}
vector<vector<int>> bucket(n);
vector<vector<int>> gap(n);
for (int i = 0; i < n; i++) {
bucket[pal[i]].push_back(i);
}
for (int i = 0; i < n - 1; i++) {
int i1 = S.sa[i + 1];
int i2 = S.sa[i + 2];
int val = S.get_lcp(i1, i2);
if (val)
gap[val - 1].push_back(i);
}
IntervalJoin I; I.init(n);
BIT<long long> bit;
bit.init(n);
for (int i = n - 1; i >= 0; i--) {
for (int x : bucket[i]) {
bit.add(S.isa[x] - 1, 1);
}
for (int x : gap[i]) {
I.unite(x, x + 1);
}
for (int x : bucket[i]) {
int y = S.isa[x]-1;
pi p = I.get_interval(y);
int res = bit.query(p.first, p.second);
ans = max(ans, 1LL * (2 * i + 1) * res);
}
}
;
}
cout << ans << '\n';
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
364 KB |
Output is correct |
2 |
Correct |
1 ms |
380 KB |
Output is correct |
3 |
Correct |
0 ms |
364 KB |
Output is correct |
4 |
Correct |
1 ms |
364 KB |
Output is correct |
5 |
Correct |
1 ms |
364 KB |
Output is correct |
6 |
Correct |
1 ms |
384 KB |
Output is correct |
7 |
Correct |
1 ms |
384 KB |
Output is correct |
8 |
Correct |
1 ms |
364 KB |
Output is correct |
9 |
Correct |
0 ms |
364 KB |
Output is correct |
10 |
Correct |
1 ms |
364 KB |
Output is correct |
11 |
Correct |
1 ms |
364 KB |
Output is correct |
12 |
Correct |
1 ms |
364 KB |
Output is correct |
13 |
Correct |
1 ms |
364 KB |
Output is correct |
14 |
Correct |
1 ms |
364 KB |
Output is correct |
15 |
Correct |
1 ms |
364 KB |
Output is correct |
16 |
Correct |
0 ms |
364 KB |
Output is correct |
17 |
Correct |
1 ms |
364 KB |
Output is correct |
18 |
Correct |
1 ms |
364 KB |
Output is correct |
19 |
Correct |
1 ms |
364 KB |
Output is correct |
20 |
Correct |
1 ms |
364 KB |
Output is correct |
21 |
Correct |
1 ms |
364 KB |
Output is correct |
22 |
Correct |
1 ms |
364 KB |
Output is correct |
23 |
Correct |
1 ms |
364 KB |
Output is correct |
24 |
Correct |
1 ms |
364 KB |
Output is correct |
25 |
Correct |
1 ms |
364 KB |
Output is correct |
26 |
Correct |
1 ms |
364 KB |
Output is correct |
27 |
Correct |
1 ms |
364 KB |
Output is correct |
28 |
Correct |
1 ms |
384 KB |
Output is correct |
29 |
Correct |
1 ms |
364 KB |
Output is correct |
30 |
Correct |
1 ms |
364 KB |
Output is correct |
31 |
Correct |
1 ms |
364 KB |
Output is correct |
32 |
Correct |
1 ms |
364 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
492 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Correct |
1 ms |
492 KB |
Output is correct |
6 |
Correct |
1 ms |
492 KB |
Output is correct |
7 |
Correct |
1 ms |
512 KB |
Output is correct |
8 |
Correct |
1 ms |
492 KB |
Output is correct |
9 |
Correct |
1 ms |
492 KB |
Output is correct |
10 |
Correct |
1 ms |
492 KB |
Output is correct |
11 |
Correct |
1 ms |
492 KB |
Output is correct |
12 |
Correct |
1 ms |
492 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
2196 KB |
Output is correct |
2 |
Correct |
8 ms |
2068 KB |
Output is correct |
3 |
Correct |
8 ms |
2284 KB |
Output is correct |
4 |
Correct |
8 ms |
2196 KB |
Output is correct |
5 |
Correct |
8 ms |
2068 KB |
Output is correct |
6 |
Correct |
7 ms |
1940 KB |
Output is correct |
7 |
Correct |
7 ms |
2088 KB |
Output is correct |
8 |
Correct |
8 ms |
1940 KB |
Output is correct |
9 |
Correct |
8 ms |
1940 KB |
Output is correct |
10 |
Correct |
8 ms |
2068 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
85 ms |
20760 KB |
Output is correct |
2 |
Correct |
83 ms |
18712 KB |
Output is correct |
3 |
Correct |
88 ms |
20768 KB |
Output is correct |
4 |
Correct |
86 ms |
19220 KB |
Output is correct |
5 |
Correct |
108 ms |
17864 KB |
Output is correct |
6 |
Correct |
104 ms |
18200 KB |
Output is correct |
7 |
Correct |
90 ms |
18080 KB |
Output is correct |
8 |
Correct |
118 ms |
17380 KB |
Output is correct |
9 |
Correct |
102 ms |
18092 KB |
Output is correct |
10 |
Correct |
110 ms |
18200 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
284 ms |
63480 KB |
Output is correct |
2 |
Correct |
280 ms |
54808 KB |
Output is correct |
3 |
Correct |
298 ms |
63788 KB |
Output is correct |
4 |
Correct |
286 ms |
56336 KB |
Output is correct |
5 |
Correct |
458 ms |
55892 KB |
Output is correct |
6 |
Correct |
310 ms |
55696 KB |
Output is correct |
7 |
Correct |
320 ms |
54672 KB |
Output is correct |
8 |
Correct |
518 ms |
53724 KB |
Output is correct |
9 |
Correct |
492 ms |
53412 KB |
Output is correct |
10 |
Correct |
436 ms |
56164 KB |
Output is correct |
11 |
Correct |
281 ms |
61304 KB |
Output is correct |
12 |
Correct |
476 ms |
54112 KB |
Output is correct |