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 <vector>
#include <algorithm>
#include <iostream>
#include <set>
#include <cmath>
#include <map>
#include <random>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <queue>
#include <limits.h>
using namespace std;
int64_t binPow (int64_t x, int64_t y, int64_t MOD) {
x %= MOD;
int64_t res = x;
int64_t ans = 1;
while (y > 0) {
if (y & 1) {
ans *= res, ans %= MOD;
}
res *= res, res %= MOD;
y /= 2;
}
return ans;
}
int64_t inv (int64_t x, int64_t MOD) {
return binPow(x, MOD - 2, MOD);
}
vector<int64_t> powr = {1};
vector<int64_t> ipowr = {1};
struct Hasher {
void resz (int mod, int base, string str) {
int n = str.size();
this->sz = n;
this->MOD = mod, this->BASE = base;
this->pref.assign(n + 1, 0);
for (int i = 1; i <= n; i++) {
pref[i] = (pref[i - 1] + (powr[n - i] * (str[i - 1] - 'a' + 1)) % MOD) % MOD;
pref[i] %= MOD;
}
}
int sz;
int MOD;
int BASE;
vector<int64_t> pref;
int64_t query (int l, int r) {
return (ipowr[sz - r - 1] * (pref[r + 1] - pref[l] + MOD) % MOD) % MOD;
}
};
Hasher h1;
Hasher h2;
string s1;
bool isPalindrome (int l, int r) {
if (l < 0 || r >= s1.length()) return false;
return (h1.query(l, r) == h2.query((int)s1.length() - r - 1, (int)s1.length() - l - 1));
}
vector<int> sort_cyclic_shifts(string const& s) {
int n = s.size();
const int alphabet = 256;
vector<int> p(n), c(n), cnt(max(alphabet, n), 0);
for (int i = 0; i < n; i++)
cnt[s[i]]++;
for (int i = 1; i < alphabet; i++)
cnt[i] += cnt[i - 1];
for (int i = 0; i < n; i++)
p[--cnt[s[i]]] = i;
c[p[0]] = 0;
int classes = 1;
for (int i = 1; i < n; i++) {
if (s[p[i]] != s[p[i - 1]])
classes++;
c[p[i]] = classes - 1;
}
vector<int> pn(n), cn(n);
for (int h = 0; (1 << h) < n; ++h) {
for (int i = 0; i < n; i++) {
pn[i] = p[i] - (1 << h);
if (pn[i] < 0)
pn[i] += n;
}
fill(cnt.begin(), cnt.begin() + classes, 0);
for (int i = 0; i < n; i++)
cnt[c[pn[i]]]++;
for (int i = 1; i < classes; i++)
cnt[i] += cnt[i-1];
for (int i = n-1; i >= 0; i--)
p[--cnt[c[pn[i]]]] = pn[i];
cn[p[0]] = 0;
classes = 1;
for (int i = 1; i < n; i++) {
pair<int, int> cur = {c[p[i]], c[(p[i] + (1 << h)) % n]};
pair<int, int> prev = {c[p[i-1]], c[(p[i-1] + (1 << h)) % n]};
if (cur != prev)
++classes;
cn[p[i]] = classes - 1;
}
c.swap(cn);
}
return p;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
while (powr.size() != 1e6 + 5) {
powr.push_back(powr.back() * 31);
powr.back() %= (int)1e9 + 9;
}
ipowr.resize(powr.size());
ipowr[0] = 1; ipowr[1] = inv(powr[1], 1e9 + 9);
for (int i = 2; i < powr.size(); i++) {
ipowr[i] = (ipowr[i - 1] * ipowr[1]) % ((int)1e9 + 9);
}
cin >> s1;
h1.resz((int)1e9 + 9, 31, s1);
reverse(s1.begin(), s1.end());
h2.resz((int)1e9 + 9, 31, s1);
reverse(s1.begin(), s1.end());
vector<pair<int,int>> vec;
for (int i = 0; i < s1.size(); i++) {
int l = 0;
int r = s1.length();
while (l != r) {
//cout << l << " " << r << '\n';
int m = (l + r + 1)/2;
if (isPalindrome(i - m, i + m)) {
l = m;
} else {
r = m - 1;
}
}
vec.emplace_back(i - l, i + l);
//[...aa...]
if (i == s1.length() || s1[i] != s1[i + 1]) {
continue;
}
l = 0;
r = s1.length();
while (l != r) {
int m = (l + r + 1)/2;
if (isPalindrome(i - m, i + m + 1)) {
l = m;
} else {
r = m - 1;
}
}
vec.emplace_back(i - l, i + l + 1);
//cout << i << " " << l << '\n';
}
map<int64_t,pair<int,int>> myMap;
for (auto& p: vec) {
pair<int,int> q = p;
while (q.first <= q.second) {
if (myMap.count(h1.query(q.first, q.second))) {
break;
}
myMap[h1.query(q.first, q.second)] = q;
q.first++, q.second--;
}
}
vector<int> v = sort_cyclic_shifts(s1);
map<int,int> id;
for (int i = 0; i < v.size(); i++) {
id[v[i]] = i;
}
int64_t ans = 0;
for (auto& p: myMap) {
//cout << p.first << " " << p.second.first << " " << p.second.second << '\n';
int tot = h1.query(p.second.first, p.second.second);
int l = 0;
int r = id[p.second.first];
while (l != r) {
int m = (l + r)/2;
if (h1.query(v[m], v[m] + p.second.second - p.second.first) == tot) {
r = m;
} else {
l = m + 1;
}
}
int L = l;
l = id[p.second.first];
r = s1.length() - 1;
while (l != r) {
int m = (l + r + 1)/2;
if (h1.query(v[m], v[m] + p.second.second - p.second.first) == tot) {
l = m;
} else {
r = m - 1;
}
}
//cout << l << " " << id[p.second.first] << '\n';
//cout << p.second.first << " " << p.second.second << " " << l - L + 1 << '\n';
//cout << p.second.first << " " << p.second.second << " " << l - L + 1 << '\n';
ans = max(ans, (int64_t)(p.second.second - p.second.first + 1) * (l - L + 1));
}
cout << ans;
}
Compilation message (stderr)
palindrome.cpp: In function 'bool isPalindrome(int, int)':
palindrome.cpp:56:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
56 | if (l < 0 || r >= s1.length()) return false;
| ~~^~~~~~~~~~~~~~
palindrome.cpp: In function 'int main()':
palindrome.cpp:112:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
112 | for (int i = 2; i < powr.size(); i++) {
| ~~^~~~~~~~~~~~~
palindrome.cpp:121:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
121 | for (int i = 0; i < s1.size(); i++) {
| ~~^~~~~~~~~~~
palindrome.cpp:135:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
135 | if (i == s1.length() || s1[i] != s1[i + 1]) {
| ~~^~~~~~~~~~~~~~
palindrome.cpp:164:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
164 | for (int i = 0; i < v.size(); i++) {
| ~~^~~~~~~~~~
# | 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... |