結果

問題 No.765 ukuku 2
ユーザー rogi52rogi52
提出日時 2022-02-22 17:45:04
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 4,717 bytes
コンパイル時間 2,209 ms
コンパイル使用メモリ 206,300 KB
実行使用メモリ 16,324 KB
最終ジャッジ日時 2023-09-13 08:16:00
合計ジャッジ時間 23,159 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 1 ms
4,376 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 AC 2 ms
4,376 KB
testcase_10 WA -
testcase_11 AC 2 ms
4,376 KB
testcase_12 WA -
testcase_13 AC 2 ms
4,376 KB
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 AC 2 ms
4,376 KB
testcase_21 AC 1 ms
4,380 KB
testcase_22 AC 2 ms
4,376 KB
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 AC 2 ms
4,376 KB
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
testcase_33 AC 276 ms
16,032 KB
testcase_34 AC 275 ms
16,120 KB
testcase_35 AC 1,134 ms
16,060 KB
testcase_36 WA -
testcase_37 WA -
testcase_38 WA -
testcase_39 WA -
testcase_40 AC 841 ms
13,360 KB
testcase_41 WA -
testcase_42 WA -
testcase_43 WA -
testcase_44 WA -
testcase_45 WA -
testcase_46 WA -
testcase_47 WA -
testcase_48 WA -
testcase_49 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

struct RollingHash {
    static constexpr int M = 2;
    static constexpr long long MODS[M] = {999999937, 1000000007};
    static constexpr long long BASE = 9973;
    vector<long long> powb[M], hash[M];
    int n;
    RollingHash() {}
    RollingHash(const string& str) { init(str); }
    void init(const string& str) {
        n = str.size();
        for (int k = 0; k < M; k++) {
            powb[k].resize(n + 1, 1);
            hash[k].resize(n + 1, 0);
            for (int i = 0; i < n; i++) {
                hash[k][i + 1] = (hash[k][i] * BASE + str[i]) % MODS[k];
                powb[k][i + 1] = powb[k][i] * BASE % MODS[k];
            }
        }
    }
    // get hash str[l,r)
    long long get(int l, int r, int k) {
        long long res = hash[k][r] - hash[k][l] * powb[k][r - l] % MODS[k];
        if (res < 0) res += MODS[k];
        return res;
    }
};

bool match(RollingHash& rh1, int l1, int r1, RollingHash& rh2, int l2, int r2) {
    bool res = true;
    for (int k = 0; k < RollingHash::M; k++) {
        res &= rh1.get(l1, r1, k) == rh2.get(l2, r2, k);
    }
    return res;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    string S; cin >> S;
    int N = S.size();
    RollingHash HS(S);
    reverse(S.begin(), S.end());
    string T = S;
    RollingHash HT(T);
    reverse(S.begin(), S.end());

    // S = [ab]c[de]fg [0,2) と [3,5)
    // T = gf[ed]c[ba] [2, 4)

    auto id = [&](int i) {
        return N - i;
    };

    int ans = 0;
    rep(i,N) {
        // odd 回文 .. S[i] .. : .. の最大の長さ
        int len = 0;
        {
            auto f = [&](int x) {
                if(!(0 <= i - x) || !(i + x < N)) return false;
                return match(HS, i - x, i, HT, id(i + 1 + x), id(i + 1));
            };
            int ok = 0, ng = N;
            while(ng - ok > 1) { int x = (ng + ok) / 2; (f(x) ? ok : ng) = x; }
            len = ok;
        }
        ans = max(ans, len + len);
        // S[i - len] .. S[i] .. S[i + len]
        // erase S[i - len - 1]
        if (i - len - 1 >= 0) {
            auto f = [&](int x) {
                if(!(0 <= i - len - 1 - x) || !(i + len + x < N)) return false;
                return match(HS, i - len - 1 - x, i - len - 1, HT, id(i + len + x), id(i + len)); 
            };
            int ok = 0, ng = N;
            while(ng - ok > 1) { int x = (ng + ok) / 2; (f(x) ? ok : ng) = x; }
            ans = max(ans, ok + len + 1 + len + ok);
        }
        // erase S[i + len + 1]
        if(i + len + 1 < N) {
            auto f = [&](int x) {
                if(!(0 <= i - len - x) || !(i + len + 1 + x < N)) return false;
                return match(HS, i - len - x, i - len, HT, id(i + len + 1 + x), id(i + len + 1));
            };
            int ok = 0, ng = N;
            while(ng - ok > 1) { int x = (ng + ok) / 2; (f(x) ? ok : ng) = x; }
            ans = max(ans, ok + len + 1 + len + ok);
        }

        if(i + 1 < N) {
            // even 回文 .. S[i] S[i+1] .. : .. の最大の長さ
            len = 0;
            {
                auto f = [&](int x) {
                    if(!(0 <= i - x) || !(i + 1 + 1 + x < N)) return false;
                    return match(HS, i - x, i, HT, id(i + 1 + 1 + x), id(i + 1 + 1));
                };
                int ok = 0, ng = N;
                while(ng - ok > 1) { int x = (ng + ok) / 2; (f(x) ? ok : ng) = x; }
                len = ok;
            }

            // S[i - len] .. S[i] S[i+1] .. S[i + 1 + len]
            // erase S[i - len - 1]
            if(i - len - 1 >= 0) {
                auto f = [&](int x) {
                    if(!(0 <= i - len - 1 - x) || !(i + 1 + len + 1 + x < N)) return false;
                    return match(HS, i - len - 1 - x, i - len - 1, HT, id(i + 1 + len + 1 + x), id(i + 1 + len + 1));
                };
                int ok = 0, ng = N;
                while(ng - ok > 1) { int x = (ng + ok) / 2; (f(x) ? ok : ng) = x; }
                ans = max(ans, ok + len + len + ok);
            }

            // erase S[i + 1 + len + 1]
            if(i + 1 + len + 1 < N) {
                auto f = [&](int x) {
                    if(!(0 <= i - len - x) || !(i + 1 + len + 1 + 1 + x < N)) return false;
                    return match(HS, i - len - x,  i - len, HT, id(i + 1 + len + 1 + 1 + x), id(i + 1 + len + 1 + 1));
                };
                int ok = 0, ng = N;
                while(ng - ok > 1) { int x = (ng + ok) / 2; (f(x) ? ok : ng) = x; }
                ans = max(ans, ok + len + len + ok);
            }
        }
    }

    cout << ans << endl;
}
0