結果
| 問題 |
No.765 ukuku 2
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:10:41 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,553 bytes |
| コンパイル時間 | 249 ms |
| コンパイル使用メモリ | 82,564 KB |
| 実行使用メモリ | 91,688 KB |
| 最終ジャッジ日時 | 2025-05-14 13:12:06 |
| 合計ジャッジ時間 | 6,705 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 19 WA * 9 TLE * 1 -- * 19 |
ソースコード
import sys
import bisect
# Function to compute the length of the Longest Common Subsequence (LCS)
# between two strings S and SR using an O(N log N) approach, where N = len(S).
# This is used to find the length of the Longest Palindromic Subsequence (LPS)
# by computing LCS(S, S_reversed).
def compute_LCS_NlogN(S, SR):
"""
Computes the length of the Longest Common Subsequence (LCS) between strings S and SR.
Uses an approach based on finding the Longest Increasing Subsequence (LIS)
on indices of matching characters, optimized to O(N log N).
Args:
S: The first string.
SR: The second string (typically the reverse of S for LPS computation).
Returns:
The length of the LCS of S and SR.
"""
N = len(S)
if N == 0:
return 0
# Precompute positions of each character in the second string SR.
# Store positions as lists indexed by character code (0-25 for 'a'-'z').
# This avoids dictionary overhead and might be slightly faster.
pos_in_SR_list = [[] for _ in range(26)]
for j in range(N):
char_code = ord(SR[j]) - ord('a')
pos_in_SR_list[char_code].append(j)
# `tails` list stores the smallest ending index `j` in SR
# for a common subsequence of length `k+1`.
# Specifically, `tails[k]` holds the smallest ending index `j` in SR
# for an LCS of length `k+1`. This is analogous to the Patience Sorting algorithm for LIS.
tails = []
# Iterate through the first string S character by character.
for i in range(N):
char_code = ord(S[i]) - ord('a')
# Retrieve the list of indices where this character appears in SR.
# The list could be empty if the character S[i] is not present in SR.
indices_j = pos_in_SR_list[char_code]
# If the character S[i] exists in SR:
if indices_j:
# Process these positions `j` in decreasing order.
# This order is crucial for correctness when characters repeat.
# It ensures that for a fixed `i`, multiple matches `j` are handled
# such that earlier occurrences `j` in SR can potentially start
# longer common subsequences.
for j in reversed(indices_j):
# Find the insertion point for `j` in the `tails` list using binary search.
# `bisect_left(tails, j)` returns the smallest index `idx` such that `tails[idx] >= j`.
idx = bisect.bisect_left(tails, j)
# If `idx == len(tails)`, it means `j` is greater than all current tail elements
# stored in `tails`. This signifies that the match (i, j) extends the
# longest common subsequence found so far by one.
if idx == len(tails):
tails.append(j)
# Otherwise, `j` is less than or equal to `tails[idx]`.
# This means we've found a common subsequence of length `idx+1` that ends at index `j` in SR.
# If `j` is smaller than the current `tails[idx]`, it provides a "better" ending point
# for an LCS of length `idx+1` (smaller ending index `j` might allow for more extensions later).
# We update `tails[idx]` with `j`.
else:
tails[idx] = j
# The length of the LCS is simply the number of elements currently stored in `tails`.
return len(tails)
# Main part of the solution
def solve():
# Read input string S from standard input.
S = sys.stdin.readline().strip()
N = len(S)
# Handle edge cases for empty or single-character strings.
# If N <= 1, deleting one character results in an empty or single-character string.
# The longest palindrome in an empty string has length 0.
# The longest palindrome in a single-char string has length 1.
# However, the problem statement says N >= 2. Let's check N=2.
# If N=2, S=s1s2. Delete s1 -> s2 (LPS 1). Delete s2 -> s1 (LPS 1). Max is 1.
# Let's adjust the base case logic to N<=1 returning 0.
if N <= 1:
# According to constraints N >= 2. But robust code handles this.
# If N=1, delete the only char -> empty string, LPS=0.
# If N=0, empty string, LPS=0.
print(0)
return
# Compute the reverse of S.
SR = S[::-1]
# Compute the length of the Longest Palindromic Subsequence (LPS) of S.
# This is equivalent to finding the LCS between S and its reverse SR.
L = compute_LCS_NlogN(S, SR)
# The core logic derived from analysis:
# If the length L of the LPS of S equals N, it implies S itself is a palindrome.
# In this case, deleting any single character from S will result in a string S'.
# The maximum possible LPS length for any such S' is N-1. This maximum is achievable.
if L == N:
print(N - 1)
# If L < N, S is not a palindrome whose length equals N.
# It can be shown that there exists at least one character in S whose removal
# does not affect *some* specific Longest Palindromic Subsequence P of length L.
# Therefore, after deleting such a character, the resulting string S' still contains P as a subsequence.
# The LPS length of S' is at least L. Since deleting a character cannot increase the LPS length,
# the maximum LPS length achievable after deleting one character is exactly L.
else:
print(L)
# Execute the solver function wrapped in a check for script execution context.
if __name__ == '__main__':
solve()
qwewe