This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
string to_string(string s) { return s; }
template <typename T> string to_string(T v) {
bool first = true;
string res = "[";
for (const auto &x : v) {
if (!first)
res += ", ";
first = false;
res += to_string(x);
}
res += "]";
return res;
}
void dbg_out() { cout << endl; }
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
cout << ' ' << to_string(H);
dbg_out(T...);
}
#ifdef DEBUG
#define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif
const int MAX_TRA = 26; // number of transitions
int normalize(char c) { // normalize `c` in [0, ..., MAX_TRA-1]
return c - 'a';
}
struct PalindromicTree {
// len = length of the palindrome, sufCount = number of suffix palindrome
// link = node of the maximum suffix palindrome, occAsMax = used in computeOcc
struct Node {
int len, link, sufCount, occAsMax, occ;
array<int, MAX_TRA> next;
Node() : occAsMax(0), occ(0) { next.fill(-1); }
};
string s;
vector<Node> t; // tree. node 0: root with len -1, node 1: root with len 0
int suff; // node of the current maximum suffix palindrome
PalindromicTree() {
suff = 1;
t.resize(2);
t[0].len = -1;
t[0].link = 0;
t[0].sufCount = 0;
t[1].len = 0;
t[1].link = 0;
t[1].sufCount = 0;
}
int suffix(int x, int i) {
while (i - t[x].len - 1 < 0 || s[i - t[x].len - 1] != s[i])
x = t[x].link;
return x;
}
// returns true if `c` created a new distinct palindrome
bool add(char c) {
int let = normalize(c);
int pos = s.size();
s.push_back(c);
suff = suffix(suff, pos);
bool newNode = t[suff].next[let] == -1;
if (newNode) {
int x = t.size();
t[suff].next[let] = x;
dbg(x);
t.emplace_back();
t[x].len = t[suff].len + 2;
t[x].link = suff == 0 ? 1 : t[suffix(t[suff].link, pos)].next[let];
t[x].sufCount = 1 + t[t[x].link].sufCount;
}
int x = t[suff].next[let];
++t[x].occAsMax;
suff = x;
return newNode;
}
void getOcc() {
for (int i = (int)t.size() - 1; i >= 0; --i) {
t[i].occ += t[i].occAsMax;
t[t[i].link].occ += t[i].occ;
}
t[0].occ = t[1].occ = 0;
}
};
signed main(void) {
ios_base::sync_with_stdio(false);
cin.tie(0);
string s;
cin >> s;
PalindromicTree tree;
for (char c : s)
tree.add(c);
tree.getOcc();
long long sol = 0;
for (int i = 2; i < (int)tree.t.size(); ++i) {
int len = tree.t[i].len;
int occ = tree.t[i].occ;
dbg(len, occ);
sol = max(sol, len * 1LL * occ);
}
cout << sol << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |