結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 12:52:01 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,134 bytes |
| コンパイル時間 | 193 ms |
| コンパイル使用メモリ | 82,096 KB |
| 実行使用メモリ | 690,048 KB |
| 最終ジャッジ日時 | 2025-05-14 12:53:47 |
| 合計ジャッジ時間 | 7,945 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 7 TLE * 2 MLE * 1 -- * 2 |
ソースコード
import sys
from collections import defaultdict
def main():
S = sys.stdin.readline().strip()
T = sys.stdin.readline().strip()
# Precompute pow_base arrays for two different hashes
base1 = 911382629
mod1 = 10**18 + 3
base2 = 3571428571
mod2 = 10**18 + 7
max_pow = 2 * 500000 + 10 # Sufficiently large to cover max possible palindrome length
pow1 = [1] * (max_pow + 1)
pow2 = [1] * (max_pow + 1)
for i in range(1, max_pow + 1):
pow1[i] = (pow1[i-1] * base1) % mod1
pow2[i] = (pow2[i-1] * base2) % mod2
def build_pal_tree(s):
tree = []
# Initialize with two root nodes: odd (0) and even (1)
tree.append({'len': -1, 'fail': 0, 'next': defaultdict(int), 'h1': 0, 'h2': 0, 'cnt': 0}) # Odd root
tree.append({'len': 0, 'fail': 0, 'next': defaultdict(int), 'h1': 0, 'h2': 0, 'cnt': 0}) # Even root
last = 1 # Initially points to even root
s_arr = list(s)
for i in range(len(s_arr)):
c = s_arr[i]
current = last
# Find the current node to expand
while True:
curr_len = tree[current]['len']
# Calculate the position to check
pos = i - curr_len - 1
if pos >= 0 and s_arr[pos] == c:
break
current = tree[current]['fail']
# Check if the child exists
if tree[current]['next'][c] != 0:
last = tree[current]['next'][c]
tree[last]['cnt'] += 1
continue
# Create new node
new_node = {
'len': tree[current]['len'] + 2,
'fail': 0,
'next': defaultdict(int),
'h1': 0,
'h2': 0,
'cnt': 1
}
# Calculate hash values
if current == 0: # Parent is odd root
new_h1 = ord(c)
new_h2 = ord(c)
else:
p_len = tree[current]['len']
new_h1 = (ord(c) * pow1[p_len + 1] + tree[current]['h1'] * base1 + ord(c)) % mod1
new_h2 = (ord(c) * pow2[p_len + 1] + tree[current]['h2'] * base2 + ord(c)) % mod2
new_node['h1'] = new_h1
new_node['h2'] = new_h2
tree.append(new_node)
new_node_idx = len(tree) - 1
tree[current]['next'][c] = new_node_idx
# Set fail for the new node
if new_node['len'] == 1:
new_node['fail'] = 1
else:
# Find the fail node
fail_current = tree[current]['fail']
while True:
flen = tree[fail_current]['len']
pos = i - flen - 1
if pos >= 0 and s_arr[pos] == c:
if tree[fail_current]['next'][c] != 0:
new_node['fail'] = tree[fail_current]['next'][c]
break
else:
fail_current = tree[fail_current]['fail']
else:
fail_current = tree[fail_current]['fail']
last = new_node_idx
# Accumulate counts
nodes_order = sorted(range(len(tree)), key=lambda x: -tree[x]['len'])
for node_idx in nodes_order:
if node_idx <= 1:
continue # Skip roots
fail_idx = tree[node_idx]['fail']
if fail_idx >= 0 and fail_idx < len(tree):
tree[fail_idx]['cnt'] += tree[node_idx]['cnt']
# Build hash map
hash_map = defaultdict(int)
for node in tree:
if node['len'] <= 0:
continue
h = (node['h1'], node['h2'])
hash_map[h] += node['cnt']
return hash_map
s_hash = build_pal_tree(S)
t_hash = build_pal_tree(T)
result = 0
for h, cnt_s in s_hash.items():
cnt_t = t_hash.get(h, 0)
if cnt_t > 0:
result += cnt_s * cnt_t
print(result)
if __name__ == "__main__":
main()
qwewe