結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 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()
qwewe