Submission #516800

#TimeUsernameProblemLanguageResultExecution timeMemory
516800shrimbPalindromes (APIO14_palindrome)C++17
8 / 100
1085 ms5364 KiB
#include"bits/stdc++.h"
using namespace std;
// #define int long long
#define endl '\n'
const int mod = 10007;
const int smolp = 31;

string s;
int n;
int pref[300001];
int suff[300001];
int inv[300001];
int dp[300001];

int pw (int a, int 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];
    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 (int i = 0 ; i < n ; i++) {
        int prev_p = (i ? pref[i-1] : 0);
        pref[i] = prev_p + ((pp * (s[i]-'a'))%mod);
        pref[i] %= mod;
        pp *= smolp;
        pp %= mod;
    }

    pp = 1;

    for (int 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);
        suff[i] %= mod;
        pp *= smolp;
        pp %= mod;
    }

    int ans = 0;

    for (int i = 1 ; i <= n ; ) {
        int gg = Solve(i);
        if (gg == 0) break;
        int l = i/2, r = n/2+1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            int gg2 = Solve(m*2+1);
            if (gg2 == gg) l = m;
            else r = m;
        }
        ans = max(ans, (2*l+1) * gg);
        i = (2*l+1) + 2;
    }
    for (int i = 2 ; i <= n ;) {
        int gg = Solve(i);
        if (gg == 0) break;
        int l = i/2, r = n/2+1 ;
        while (r - l > 1) {
            int m = (l + r) / 2;
            int gg2 = Solve(m*2);
            if (gg2 == gg) l = m;
            else r = m;
        }
        ans = max(ans, (2*l) * gg);
        i = (2*l) + 2;
    }
    cout << ans << endl;

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...