結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 12:52:00 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 3,672 bytes |
| コンパイル時間 | 193 ms |
| コンパイル使用メモリ | 82,580 KB |
| 実行使用メモリ | 528,216 KB |
| 最終ジャッジ日時 | 2025-05-14 12:53:47 |
| 合計ジャッジ時間 | 9,956 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 8 TLE * 2 MLE * 2 |
ソースコード
import sys
from collections import defaultdict
def main():
S = sys.stdin.readline().strip()
T = sys.stdin.readline().strip()
base1 = 911382629
mod1 = 10**18 + 3
base2 = 3571428571
mod2 = 10**18 + 7
max_len = 10**6 + 10 # Sufficiently large to handle maximum possible length
# Precompute pow_base arrays for both bases and mods
pow_base1 = [1] * (max_len + 1)
for i in range(1, max_len + 1):
pow_base1[i] = (pow_base1[i-1] * base1) % mod1
pow_base2 = [1] * (max_len + 1)
for i in range(1, max_len + 1):
pow_base2[i] = (pow_base2[i-1] * base2) % mod2
def build_pal_tree(s):
class Node:
__slots__ = ['len', 'link', 'next', 'h1', 'h2', 'cnt']
def __init__(self):
self.len = 0
self.link = None
self.next = dict()
self.h1 = 0
self.h2 = 0
self.cnt = 0
root0 = Node()
root0.len = 0
root1 = Node()
root1.len = -1
root1.link = root1
root0.link = root1
last = root0
nodes = [root0, root1]
for i in range(len(s)):
c = s[i]
current = last
while True:
# Calculate the position of the previous character
pos = i - current.len - 1
if pos >= 0 and s[pos] == c:
break
current = current.link
if c in current.next:
last = current.next[c]
last.cnt += 1
continue
# Create a new node
new_node = Node()
new_node.len = current.len + 2
if current is root1:
new_node.h1 = ord(c)
new_node.h2 = ord(c)
else:
exponent = current.len + 1
h1_part = (ord(c) * pow_base1[exponent]) % mod1
h1_mid = (current.h1 * base1) % mod1
new_h1 = (h1_part + h1_mid + ord(c)) % mod1
h2_part = (ord(c) * pow_base2[exponent]) % mod2
h2_mid = (current.h2 * base2) % mod2
new_h2 = (h2_part + h2_mid + ord(c)) % mod2
new_node.h1 = new_h1
new_node.h2 = new_h2
# Find the link for the new node
if new_node.len == 1:
new_node.link = root0
else:
tmp = current.link
while True:
pos = i - tmp.len - 1
if pos >= 0 and s[pos] == c:
break
tmp = tmp.link
# Check if tmp has the 'c' child
new_node.link = tmp.next.get(c, root0)
current.next[c] = new_node
nodes.append(new_node)
last = new_node
last.cnt = 1
# Propagate the counts
nodes_sorted = sorted(nodes, key=lambda x: -x.len)
for node in nodes_sorted:
if node.link is not None:
node.link.cnt += node.cnt
# Collect hash map entries
hash_map = defaultdict(int)
for node in nodes:
if node is root0 or node is root1:
continue
hash_key = (node.h1, node.h2)
hash_map[hash_key] += node.cnt
return hash_map
# Build hash maps for S and T
hash_s = build_pal_tree(S)
hash_t = build_pal_tree(T)
# Calculate the result
result = 0
for key in hash_s:
if key in hash_t:
result += hash_s[key] * hash_t[key]
print(result)
if __name__ == '__main__':
main()
qwewe