結果

問題 No.2490 Escalator
ユーザー Sillpherth
提出日時 2025-04-21 20:55:09
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 2,556 bytes
コンパイル時間 832 ms
コンパイル使用メモリ 86,528 KB
実行使用メモリ 7,848 KB
最終ジャッジ日時 2025-04-21 20:55:13
合計ジャッジ時間 3,474 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 59 WA * 14
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
using namespace std;

// 小さいNの場合に使う単純な回文判定
bool simpleCheck(const vector<int>& S, int N) {
    int size = S.size();

    // 奇数長回文チェック
    for (int center = 0; center < size; ++center) {
        int length = 0;
        while (center - length >= 0 && center + length < size &&
               (S[center - length] == S[center + length] || S[center - length] == -1 || S[center + length] == -1)) {
            ++length;
        }
        if ((2 * length - 1) > N) return true;
    }

    // 偶数長回文チェック
    for (int center = 0; center + 1 < size; ++center) {
        int length = 0;
        while (center - length >= 0 && center + length + 1 < size &&
               (S[center - length] == S[center + length + 1] || S[center - length] == -1 || S[center + length + 1] == -1)) {
            ++length;
        }
        if (2 * length > N) return true;
    }

    return false;
}

// 大きいNの場合に使う高速化された回文判定
bool optimizedCheck(const vector<int>& S, int N) {
    int size = S.size();
    
    // Manacher法を使って回文長を高速に計算
    vector<int> palindrome(size, 0);
    int center = 0, right = 0;
    
    for (int i = 0; i < size; ++i) {
        int mirror = 2 * center - i;
        
        if (i < right) palindrome[i] = min(right - i, palindrome[mirror]);
        
        // 回文の拡張
        while (i + palindrome[i] < size && i - palindrome[i] >= 0 &&
               (S[i + palindrome[i]] == S[i - palindrome[i]] || S[i + palindrome[i]] == -1 || S[i - palindrome[i]] == -1)) {
            palindrome[i]++;
        }

        // 回文の右端を更新
        if (i + palindrome[i] > right) {
            center = i;
            right = i + palindrome[i];
        }

        // 回文長がNを超える場合、すぐに返す
        if (2 * palindrome[i] - 1 > N || 2 * palindrome[i] > N) return true;
    }

    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int N;
    cin >> N;
    vector<int> A(2 * N);
    for (int i = 0; i < 2 * N; ++i) {
        cin >> A[i];
    }

    // AA = A + A(連結)
    vector<int> AA(4 * N);
    for (int i = 0; i < 2 * N; ++i) {
        AA[i] = A[i];
        AA[i + 2 * N] = A[i];
    }

    // Nが大きいか小さいかで分岐
    if (N <= 1000) {
        cout << (simpleCheck(AA, N) ? "Yes" : "No") << '\n';
    } else {
        cout << (optimizedCheck(AA, N) ? "Yes" : "No") << '\n';
    }

    return 0;
}
0