結果
問題 | No.430 文字列検索 |
ユーザー | aaaaa |
提出日時 | 2021-08-12 16:17:48 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 188 ms / 2,000 ms |
コード長 | 3,787 bytes |
コンパイル時間 | 209 ms |
コンパイル使用メモリ | 82,048 KB |
実行使用メモリ | 111,360 KB |
最終ジャッジ日時 | 2024-11-10 00:57:12 |
合計ジャッジ時間 | 2,633 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 38 ms
54,144 KB |
testcase_01 | AC | 188 ms
111,360 KB |
testcase_02 | AC | 110 ms
88,192 KB |
testcase_03 | AC | 107 ms
88,064 KB |
testcase_04 | AC | 41 ms
54,016 KB |
testcase_05 | AC | 37 ms
54,528 KB |
testcase_06 | AC | 36 ms
54,272 KB |
testcase_07 | AC | 37 ms
54,528 KB |
testcase_08 | AC | 56 ms
69,760 KB |
testcase_09 | AC | 61 ms
72,704 KB |
testcase_10 | AC | 59 ms
70,016 KB |
testcase_11 | AC | 164 ms
104,044 KB |
testcase_12 | AC | 166 ms
107,264 KB |
testcase_13 | AC | 168 ms
107,264 KB |
testcase_14 | AC | 160 ms
101,120 KB |
testcase_15 | AC | 152 ms
94,592 KB |
testcase_16 | AC | 141 ms
94,720 KB |
testcase_17 | AC | 135 ms
94,468 KB |
ソースコード
from collections import defaultdict class Trie: def __init__(self, base=ord("a"), char_size=26): self.nexts = [] self.accepts = [] self.cs = [] self.commons = [] self.base = base self.char_size = char_size self.root = 0 self.words = defaultdict(set) self._construct_node(self.root) def _construct_node(self, n): for i in range(self.char_size): self.nexts.append(-1) self.accepts.append(0) self.cs.append(n) self.commons.append(0) def insert(self, word): node_id = self.root for i in range(len(word)): c = ord(word[i])-self.base next_id = self.nexts[self.char_size*node_id+c] if next_id == -1: next_id = len(self.cs) self.nexts[self.char_size*node_id+c] = next_id self._construct_node(c) self.commons[node_id] += 1 node_id = next_id self.commons[node_id] += 1 self.accepts[node_id] += 1 return node_id def search(self, word, prefix=False): node_id = self.root for i in range(len(word)): c = ord(word[i]) - self.base next_id = self.nexts[self.char_size*node_id+c] if next_id == -1: return False node_id = next_id if prefix: return True return self.accepts[node_id] > 0 def size(self): return len(self.cs) def count(self): return self.commons[0] from collections import deque, defaultdict class AhoCorasickTrie(Trie): def __init__(self, patterns, base=ord("a"), char_size=26): super().__init__(base, char_size) self.patterns = patterns self.pattern_len = [len(pat) for pat in patterns] self.matches = defaultdict(set) for i, pat in enumerate(patterns): node_id = self.insert(pat) self.matches[node_id].add(i) self.back_edge = self._BFS() def _BFS(self): back_edge = [0]*self.size() Q = deque([]) for i in range(self.char_size): v1 = self.nexts[self.char_size*self.root+i] if v1 != -1: Q.append(v1) back_edge[v1] = self.root while len(Q) > 0: v = Q.pop() if self.commons[v] == 0: continue for i in range(self.char_size): v1 = self.nexts[self.char_size*v+i] if v1 != -1: back = back_edge[v] while self.nexts[self.char_size*back+i] == -1 and back != self.root: back = back_edge[back] if self.nexts[self.char_size*back+i] == -1: back_edge[v1] = self.root else: back_edge[v1] = self.nexts[self.char_size*back+i] self.matches[v1] |= self.matches[back_edge[v1]] Q.appendleft(v1) return back_edge def match(self, S): now = self.root match_list = defaultdict(list) for i in range(len(S)): c = ord(S[i]) - self.base while self.nexts[self.char_size*now+c] == -1 and now != self.root: now = self.back_edge[now] if self.nexts[self.char_size*now+c] != -1: now = self.nexts[self.char_size*now+c] for pat in self.matches[now]: match_list[pat].append(i-self.pattern_len[pat]+1) return match_list S = input() M = int(input()) C = [input() for i in range(M)] act = AhoCorasickTrie(C, base=ord("A")) res = act.match(S) print(sum(len(c) for _,c in res.items()))