結果
問題 |
No.765 ukuku 2
|
ユーザー |
![]() |
提出日時 | 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()