結果
問題 |
No.263 Common Palindromes Extra
|
ユーザー |
![]() |
提出日時 | 2025-05-14 12:47:23 |
言語 | PyPy3 (7.3.15) |
結果 |
MLE
|
実行時間 | - |
コード長 | 4,563 bytes |
コンパイル時間 | 1,885 ms |
コンパイル使用メモリ | 81,960 KB |
実行使用メモリ | 722,148 KB |
最終ジャッジ日時 | 2025-05-14 12:48:04 |
合計ジャッジ時間 | 8,303 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 8 TLE * 2 MLE * 2 |
ソースコード
import sys from collections import defaultdict def main(): sys.setrecursionlimit(1 << 25) S = sys.stdin.readline().strip() T = sys.stdin.readline().strip() # Precompute powers for two different bases and mods max_len = max(len(S), len(T)) + 2 base1 = 911382629 base2 = 3571428571 mod1 = 10**18 + 3 mod2 = 10**18 + 7 # Precompute power arrays power1 = [1] * (max_len + 2) power2 = [1] * (max_len + 2) for i in range(1, max_len + 2): power1[i] = (power1[i-1] * base1) % mod1 power2[i] = (power2[i-1] * base2) % mod2 class Node: __slots__ = ['length', 'hash1', 'hash2', 'count', 'suffix_link', 'transitions'] def __init__(self): self.length = 0 self.hash1 = 0 self.hash2 = 0 self.count = 0 self.suffix_link = None self.transitions = dict() def build_eertree(s, power1, power2, base1, base2, mod1, mod2): root_neg = Node() root_neg.length = -1 root_neg.suffix_link = root_neg root_0 = Node() root_0.length = 0 root_0.suffix_link = root_neg root_neg.count = 0 root_0.count = 0 tree = [root_neg, root_0] current_suffix = root_0 for i in range(len(s)): c = s[i] current = current_suffix while True: link_len = current.length if link_len == -1: break # root_neg can always be extended to single character start = i - link_len - 1 if start >= 0 and s[start] == c: break current = current.suffix_link if c in current.transitions: current_suffix = current.transitions[c] current_suffix.count += 1 continue # Create new node new_node = Node() new_node.length = current.length + 2 if current == root_neg: new_node.hash1 = ord(c) new_node.hash2 = ord(c) else: exponent = current.length + 1 new_hash1 = (ord(c) * power1[exponent] + current.hash1 * base1 + ord(c)) % mod1 new_hash2 = (ord(c) * power2[exponent] + current.hash2 * base2 + ord(c)) % mod2 new_node.hash1 = new_hash1 new_node.hash2 = new_hash2 # Find suffix link for new_node if new_node.length == 1: new_node.suffix_link = root_0 else: suffix_candidate = current.suffix_link while True: link_len_candidate = suffix_candidate.length if link_len_candidate == -1: suffix_candidate = suffix_candidate.suffix_link break start_candidate = i - link_len_candidate - 1 if start_candidate >= 0 and s[start_candidate] == c: break suffix_candidate = suffix_candidate.suffix_link if c in suffix_candidate.transitions: new_node.suffix_link = suffix_candidate.transitions[c] else: if suffix_candidate == root_neg: new_node.suffix_link = root_0 else: new_node.suffix_link = root_0 current.transitions[c] = new_node tree.append(new_node) current_suffix = new_node current_suffix.count = 1 # Propagate counts for node in reversed(tree[2:]): # exclude root_neg and root_0 if node.suffix_link is not None and node.suffix_link.length >= 0: # valid suffix_link node.suffix_link.count += node.count return tree # Build Eertree for S and T s_tree = build_eertree(S, power1, power2, base1, base2, mod1, mod2) t_tree = build_eertree(T, power1, power2, base1, base2, mod1, mod2) # Create hash map for S's palindromes s_palindromes = defaultdict(int) for node in s_tree[2:]: # skip root_neg and root_0 key = (node.hash1, node.hash2) s_palindromes[key] += node.count # Calculate the answer answer = 0 for node in t_tree[2:]: # skip root_neg and root_0 key = (node.hash1, node.hash2) if key in s_palindromes: answer += s_palindromes[key] * node.count print(answer) if __name__ == "__main__": main()