結果
問題 | No.263 Common Palindromes Extra |
ユーザー | amesyu |
提出日時 | 2024-10-19 15:27:53 |
言語 | PyPy3 (7.3.15) |
結果 |
MLE
|
実行時間 | - |
コード長 | 3,694 bytes |
コンパイル時間 | 682 ms |
コンパイル使用メモリ | 82,468 KB |
実行使用メモリ | 407,416 KB |
最終ジャッジ日時 | 2024-10-19 15:28:03 |
合計ジャッジ時間 | 8,627 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | MLE | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | MLE | - |
testcase_04 | MLE | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
ソースコード
from collections import defaultdict MOD = (1<<61) - 1 BASE = 10007 MAXN = 10**6 POWER = [1] for i in range(1, MAXN+1): POWER.append((POWER[-1] * BASE) % MOD) class RollingHash: def __init__(self, string): self.string = string self.size = len(string) # construct self.hashed = [0] for i in range(self.size): self.hashed.append(self.hashed[-1] * BASE + ord(self.string[i])) self.hashed[-1] %= MOD def query(self, l, r): assert 0 <= l <= r <= self.size return (self.hashed[r] - self.hashed[l] * POWER[r-l]) % MOD def composite_query(R1, R2, l1, r1, l2, r2): LEFT = R1.query(l1, r1) RIGHT = R2.query(l2, r2) return (RIGHT + LEFT * POWER[r2-l2]) % MOD class eertree: def __init__(self, string): self.string = string self.size = len(string) self.r1 = RollingHash(self.string) self.r2 = RollingHash(''.join(reversed(self.string))) def __rev(self, l, r): return self.size - r, self.size - l def build(self): BEGIN = ord('A') # or ord('a') # Centroid of the palindrome A-Z and '' ptr = [defaultdict(lambda: -2) for _ in range(27)] lazy = [defaultdict(int) for _ in range(27)] tail = [(-1, -1) for _ in range(27)] tail[26] = (0, 0) ptr[26][0] = -1 for i in range(self.size): # Centroid = self.string[i] ok, ng = -1, min(i, self.size-i-1)+1 ID = ord(self.string[i]) - BEGIN while ng - ok > 1: x = (ng + ok) >> 1 h = self.r1.query(i+1, i+1+x) if ptr[ID][h] >= -1: ok = x else: ng = x if ok == -1: ptr[ID][0] = -1 ok = 0 prh = self.r1.query(i+1, i+1+ok) longest = ok for j in range(ok+1, min(i, self.size-i-1)+1): l1, r1 = i+1, i+1+j l2, r2 = self.__rev(i-j, i) h1 = self.r1.query(l1, r1) h2 = self.r2.query(l2, r2) if h1 == h2: longest = j ptr[ID][h1] = prh prh = h1 else: break lazy[ID][prh] += 1 tail[ID] = max(tail[ID], (longest, prh)) # Centroid = '' ok, ng = 0, min(i, self.size-i-1) + 1 ID = 26 while ng - ok > 1: x = (ng + ok) >> 1 h = self.r1.query(i, i + x) if ptr[ID][h] >= -1: ok = x else: ng = x prh = self.r1.query(i, i+ok) longest = ok for j in range(ok+1, min(i, self.size-i)+1): l1, r1 = i, i + j l2, r2 = self.__rev(i - j, i) h1 = self.r1.query(l1, r1) h2 = self.r2.query(l2, r2) if h1 == h2: longest = j ptr[ID][h1] = prh prh = h1 else: break lazy[ID][prh] += 1 tail[ID] = max(tail[ID], (longest, prh)) for ID in range(27): _, v = tail[ID] while v > 0: par = ptr[ID][v] lazy[ID][par] += lazy[ID][v] v = par lazy[26][0] = 0 return lazy s = input() t = input() palS = eertree(s) palT = eertree(t) ResultS = palS.build() ResultT = palT.build() ans = 0 for ID in range(27): for h in ResultS[ID]: ans += ResultS[ID][h] * ResultT[ID][h] print(ans)