제출 #1346310

#제출 시각아이디문제언어결과실행 시간메모리
1346310gkos5678Palinilap (COI16_palinilap)C++20
0 / 100
80 ms12364 KiB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
const int ba = 1337;

ll n, uk, uksl, hp[maxn], hs[maxn], pw[maxn], ra[2 * maxn], st[maxn], sl[maxn];
string s;
vi bs[maxn];

int add(int a, int b){
    a += b;
    if (a >= mod) a-= mod;
    return a;
}

int sub(int a, int b){
    a -= b;
    if (a < 0) a += mod;
    return a;
}

int mul(int a, int b){
    return (ll)a * b % mod;
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> s;
    n = s.size();
    s = '$' + s;
    pw[0] = 1;
    for (int i = 1; i <= n; i++)
        pw[i] = mul(pw[i - 1], ba);
    for (int i = 1; i <= n; i++)
        hp[i] = add(mul(hp[i - 1], ba), s[i] - 'a');
    for (int i = n; i > 0; i--)
        hs[i] = add(mul(hs[i + 1], ba), s[i] - 'a');

    ll ans = 0;
    for (int i = 2; i <= 2 * n; i++){
        ll sr = (i - 1) / 2;
        int l = 0, r = min(sr, n - (i - sr) + 1);
        while(l < r){
            int m = (l + r + 1) / 2;
            int le = sr - m + 1;
            int ri = i - le;
            int h1 = sub(hp[ri], mul(pw[ri - le + 1], hp[le - 1]));
            int h2 = sub(hs[le], mul(pw[ri - le + 1], hs[ri + 1]));
            if (h1 == h2) l = m;
            else r = m - 1;
        }
        ra[i] = l;
        ans += l + 1 - (i & 1);
        bs[sr - l].pb(i);
        bs[i - sr + l].pb(i);
        sl[sr - l]++;
        st[sr + 1] -= l;
        sl[sr]--;
        st[i - sr] += l;
        sl[i - sr]--;
        sl[i - sr + l]++;
    }

    ll mxdod = 0;
    uksl += sl[0];
    uk += st[0];
    for (int i = 1; i <= n; i++){
        uk += st[i] + uksl;
        uksl += sl[i];
        for (int j = 0; j < 26; j++){
            if (j == (s[i] - 'a')) continue;
            ll dod = -uk;
            for (int sm : bs[i]){
                int dr = sm - i;
                if ((s[dr] - 'a') != j) continue;
                ll sr = (sm - 1) / 2;
                int l = 0, r = min(sr, n - (sm - sr) + 1);
                while(l < r){
                    int m = (l + r + 1) / 2;
                    int le = sr - m + 1;
                    int ri = sm - le;
                    int h1 = sub(hp[ri], mul(pw[ri - le + 1], hp[le - 1]));
                    int h2 = sub(hs[le], mul(pw[ri - le + 1], hs[ri + 1]));
                    if (le <= i && i <= ri){
                        h1 = add(h1, mul(pw[ri - i], j - (s[i] - 'a')));
                        h2 = add(h2, mul(pw[i - le], j - (s[i] - 'a')));
                    }
                    if (h1 == h2) l = m;
                    else r = m - 1;
                }
                dod += l - ra[sm];
            }
            mxdod = max(mxdod, dod);
        }
    }
    cout << ans + mxdod << "\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...