結果
問題 | No.263 Common Palindromes Extra |
ユーザー |
![]() |
提出日時 | 2025-03-26 15:54:21 |
言語 | PyPy3 (7.3.15) |
結果 |
MLE
|
実行時間 | - |
コード長 | 4,014 bytes |
コンパイル時間 | 233 ms |
コンパイル使用メモリ | 82,040 KB |
実行使用メモリ | 550,772 KB |
最終ジャッジ日時 | 2025-03-26 15:55:26 |
合計ジャッジ時間 | 9,118 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 8 TLE * 2 MLE * 2 |
ソースコード
import sysfrom collections import defaultdictclass Node:__slots__ = ['len', 'link', 'next', 'cnt', 'h1', 'h2']def __init__(self):self.len = 0self.link = 0self.next = [0] * 26 # 'A' to 'Z'self.cnt = 0self.h1 = 0self.h2 = 0def build_pal_tree(s, base1, base2, mod1, mod2, pow_base1, pow_base2):nodes = []# Initialize root nodesnode = Node()node.len = -1node.link = 0nodes.append(node)node = Node()node.len = 0node.link = 0nodes.append(node)size = 2last = 1 # start with the empty nodefor i, c in enumerate(s):idx = ord(c) - ord('A')# Find the appropriate parent nodep = lastwhile True:current_len = nodes[p].len# Check if the character at position i - current_len - 1 is cif i - current_len - 1 >= 0 and s[i - current_len - 1] == c:breakp = nodes[p].link# Check if the child existsif nodes[p].next[idx] != 0:last = nodes[p].next[idx]nodes[last].cnt += 1continue# Create new nodenew_node = Node()new_node.len = nodes[p].len + 2# Compute hash valuesif nodes[p].len == -1 and new_node.len == 1:# Special case for single characternew_node.h1 = ord(c)new_node.h2 = ord(c)else:# Compute h1 and h2 using the parent's hash valuesnew_node.h1 = (ord(c) * pow_base1[nodes[p].len + 1] + nodes[p].h1 * base1 + ord(c)) % mod1new_node.h2 = (ord(c) * pow_base2[nodes[p].len + 1] + nodes[p].h2 * base2 + ord(c)) % mod2# Find the link for the new node# Start from the parent's linknew_link = 0if new_node.len == 1:new_link = 1 # link to empty nodeelse:# Find the longest proper suffix which is a palindromelink_p = nodes[p].linkwhile True:current_len_link = nodes[link_p].lenif i - current_len_link - 1 >= 0 and s[i - current_len_link - 1] == c:breaklink_p = nodes[link_p].linknew_link = nodes[link_p].next[idx]if new_link == 0:new_link = 1 # default to empty node if not found (should not happen)new_node.link = new_link# Add the new node to the listnodes.append(new_node)size += 1last = size - 1nodes[p].next[idx] = lastnew_node.cnt = 1# Accumulate counts# Sort nodes by length in descending ordernodes_sorted = sorted(nodes[2:], key=lambda x: -x.len)for node in nodes_sorted:if node.link < len(nodes) and node.link >= 0:nodes[node.link].cnt += node.cnt# Collect all hashes except the two rootshash_map = defaultdict(int)for node in nodes[2:]:key = (node.h1, node.h2)hash_map[key] += node.cntreturn hash_mapdef main():s = sys.stdin.readline().strip()t = sys.stdin.readline().strip()# Precompute powers for hash calculationbase1 = 911382629mod1 = 10**18 + 3base2 = 3571428571mod2 = 10**18 + 7max_len = max(len(s), len(t)) + 2# Precompute pow_base arrayspow_base1 = [1] * (max_len + 1)for i in range(1, max_len + 1):pow_base1[i] = (pow_base1[i-1] * base1) % mod1pow_base2 = [1] * (max_len + 1)for i in range(1, max_len + 1):pow_base2[i] = (pow_base2[i-1] * base2) % mod2# Build hash maps for both stringsmap_S = build_pal_tree(s, base1, base2, mod1, mod2, pow_base1, pow_base2)map_T = build_pal_tree(t, base1, base2, mod1, mod2, pow_base1, pow_base2)# Calculate the resultresult = 0for key in map_T:if key in map_S:result += map_S[key] * map_T[key]print(result)if __name__ == "__main__":main()