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;
#define int long long
#define endl '\n'
const int mod = 1e9+7;
const int smolp = 31;
string s;
signed n;
signed pref[300001];
signed suff[300001];
signed inv[300001];
signed dp[300001];
signed pw (int a, signed b) {
if (b == 0) return 1;
if (b == 1) return a;
if (b & 1) return (a * pw(a, b - 1)) % mod;
int y = pw(a, b / 2);
return (y*y)%mod;
}
int Solve (int sz) {
if (dp[sz] != -1) return dp[sz];
unordered_map<int,int>f;
int mxf = 0;
for (int i = sz - 1 ; i < n ; i++) {
int sub = pref[i] - (i - sz < 0 ? 0 : pref[i-sz]);
if (sub < 0) sub += mod;
sub *= inv[i - sz + 1];
sub %= mod;
int sub2 = suff[i-sz+1] - (i < n - 1 ? suff[i + 1] : 0);
if (sub2 < 0) sub2 += mod;
sub2 *= inv[(n-1) - i];
sub2 %= mod;
// cerr << sz << ": " << sub << " " << sub2 << endl;
if (sub == sub2) mxf = max(mxf, ++f[sub]);
}
return dp[sz] = mxf;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> s;
n = s.size();
int x = 1;
for (int i = 0 ; i <= n ; i++) {
inv[i] = pw(x, mod - 2);
x *= smolp;x%=mod;
}
memset(dp, -1, sizeof dp);
int pp = 1;
for (signed i = 0 ; i < n ; i++) {
int prev_p = (i ? pref[i-1] : 0);
pref[i] = (prev_p + ((pp * (s[i]-'a'))%mod))%mod;
// pref[i] %= mod;
pp *= smolp;
pp %= mod;
}
pp = 1;
for (signed i = n - 1 ; i >= 0 ; i--) {
int prev_s = (i < n - 1 ? suff[i + 1] : 0);
suff[i] = (prev_s + ((pp * (s[i] - 'a')) % mod))%mod;
// suff[i] %= mod;
pp *= smolp;
pp %= mod;
}
int ans = 0;
for (signed i = 1 ; i <= n ; ) {
signed gg = Solve(i);
if (gg == 0) break;
signed l = i/2, r = n/2+1;
while (r - l > 1) {
signed m = (l + r) / 2;
int gg2 = Solve(m*2+1)*(m*2+1);
int gg3 = Solve(m*2-1)*(m*2-1);
ans = max({ans, gg2, gg3});
if (gg2>gg3) l = m;
else r = m;
}
ans = max(ans, (int)(2*l+1) * Solve(2*l+1));
r = n/2 + 1;
l = l+1;
while (r - l > 1) {
int m = (l + r) / 2;
int gg2 = Solve(m*2+1);
if (gg2 == Solve(l*2+1)) l = m;
else r = m;
}
ans = max(ans, (int)(2*l+1) * Solve(2*l+1));
i = 2*l+1;
}
for (signed i = 2 ; i <= n ;) {
signed gg = Solve(i);
if (gg == 0) break;
signed l = i/2, r = n/2+1 ;
while (r - l > 1) {
signed m = (l + r) / 2;
int gg2 = Solve(m*2)*(m*2);
int gg3 = Solve(m*2-2)*(m*2-2);
ans = max({ans, gg2, gg3});
if (gg2>gg3) l = m;
else r = m;
}
ans = max(ans, (int)(2*l) * Solve(2*l));
r = n/2 + 1;
l = l+1;
while (r - l > 1) {
int m = (l + r) / 2;
int gg2 = Solve(m*2);
if (gg2 == Solve(l*2)) l = m;
else r = m;
}
ans = max(ans, (int)(2*l) * Solve(2*l));
i = 2*l;
}
cout << ans << 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... |