結果

問題 No.3392 Count 23578 Sequence
コンテスト
ユーザー LyricalMaestro
提出日時 2026-05-25 02:10:53
言語 PyPy3
(7.3.17)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
TLE  
実行時間 -
コード長 2,747 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 229 ms
コンパイル使用メモリ 85,516 KB
実行使用メモリ 372,844 KB
最終ジャッジ日時 2026-05-25 02:12:24
合計ジャッジ時間 22,792 ms
ジャッジサーバーID
(参考情報)
judge1_0 / judge2_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 4 TLE * 12 -- * 32
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

## https://yukicoder.me/problems/no/3392


MOD = 998244353

H = 9007199254740997

    

def main():
    N = int(input())
    A = list(map(int, input().split()))

    answer = N
    if N == 1:
        print(answer)
        return

    diff_A = []
    for i in range(N - 1):
        diff_A.append(A[i + 1] - A[i])
    
    # diff_Aの中に回文がいくつあるかの問題に帰着する

    # 1. 座標圧縮
    a_set = set(diff_A)
    a_list = list(a_set)
    a_list.sort()
    a_map = {}
    for i, a in enumerate(a_list):
        a_map[a] = i + 1

    diff_A2 = [a_map[diff_A[i]] for i in range(len(diff_A))]

    max_a = max(diff_A2)

    B = max_a + 1
    # ローリングハッシュ計算
    forward_hash = [0] * (N -1)
    h = 0
    for i in range(N - 1):
        h *= B
        h %= H
        h += diff_A2[i]
        h %= H
        forward_hash[i] = h
    backward_hash = [0] * (N - 1)
    h = 0
    for i in reversed(range(N - 1)):
        h *= B
        h %= H
        h += diff_A2[i]
        h %= H
        backward_hash[i] = h

    pow_b = [0] * N
    b = 1
    for i in range(N):
        pow_b[i] = b
        b *= B
        b %= H

    def solve(forward_hash, backward_hash, i, l):
        b = (backward_hash[i - l] - ((backward_hash[i] * pow_b[l]) % H)) % H
        f = (forward_hash[i + l] - ((forward_hash[i] * pow_b[l]) % H)) % H
        return b == f

    # 計算(奇数長)
    for i in range(N - 1):
        left = i
        right = N - 2 - i
        max_length = min(left, right)

        low = 0
        high = max_length
        while high - low > 1:
            mid = (high + low) // 2
            if solve(forward_hash, backward_hash, i, mid):
                low = mid
            else:
                high = mid
        if solve(forward_hash, backward_hash, i, high):
            answer += 1 + high
        else:
            answer += 1 + low

    def solve2(forward_hash, backward_hash, i, l):
        b = (backward_hash[i - l] - ((backward_hash[i + 1] * pow_b[l]) % H)) % H
        f = (forward_hash[i + 1 + l] - ((forward_hash[i] * pow_b[l]) % H)) % H
        return b == f

    # 計算(偶数長)
    for i in range(N - 2):
        if diff_A2[i] != diff_A2[i + 1]:
            continue

        left = i
        right = N - 2 - (i + 1)

        max_length = min(left, right)
        low = 0
        high = max_length
        while high - low > 1:
            mid = (high + low) // 2
            if solve2(forward_hash, backward_hash, i, mid):
                low = mid
            else:
                high = mid
        if solve2(forward_hash, backward_hash, i, high):
            answer += 1 + high
        else:
            answer += 1 + low
    print(answer)




if __name__ == "__main__":
    main()
0