結果
| 問題 | No.3392 Count 23578 Sequence |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-05-25 23:32:06 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,738 bytes |
| 記録 | |
| コンパイル時間 | 402 ms |
| コンパイル使用メモリ | 85,376 KB |
| 実行使用メモリ | 373,340 KB |
| 最終ジャッジ日時 | 2026-05-25 23:33:53 |
| 合計ジャッジ時間 | 10,183 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 32 TLE * 16 |
ソースコード
## https://yukicoder.me/problems/no/3392
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 + 1]) % H)) % H
f = (forward_hash[i + 1 + l] - ((forward_hash[i] * pow_b[l + 1]) % 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()