結果
問題 |
No.2761 Substitute and Search
|
ユーザー |
|
提出日時 | 2025-03-09 03:45:31 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,648 bytes |
コンパイル時間 | 765 ms |
コンパイル使用メモリ | 81,732 KB |
実行使用メモリ | 255,156 KB |
最終ジャッジ日時 | 2025-03-09 03:45:39 |
合計ジャッジ時間 | 7,634 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 1 TLE * 1 -- * 11 |
ソースコード
## https://yukicoder.me/problems/no/2957 B = 30 H = 9007199254740997 from collections import deque class SegmentTree: """ 非再帰版セグメント木。 更新は「加法」、取得は「最大値」のもの限定。 """ def __init__(self, init_array, pow_b): n = 1 while n < len(init_array): n *= 2 self.size = n self.pow_b = pow_b self.l_queue = deque() self.r_queue = deque() self.array = [0] * (2 * self.size) self.weights = [0] * (2 * self.size) for i, a in enumerate(init_array): self.array[self.size + i] = a self.weights[self.size + i] = 1 end_index = self.size start_index = end_index // 2 while start_index >= 1: for i in range(start_index, end_index): self.weights[i] = self.weights[2 * i] + self.weights[2 * i + 1] self.array[i] = self._op(2 * i, 2 * i + 1) end_index = start_index start_index = end_index // 2 def _op(self, l, r): a = (self.pow_b[self.weights[r]] * self.array[l]) % H a += self.array[r] a %= H return a def set(self, x, a): index = self.size + x self.array[index] = a while index > 1: index //= 2 self.array[index] = self._op(2 * index, 2 * index + 1) def get_sum(self, l, r): L = self.size + l; R = self.size + r # 2. 区間[l, r)の最大値を求める while L < R: if R & 1: R -= 1 self.r_queue.appendleft(R) if L & 1: self.l_queue.append(L) L += 1 L >>= 1; R >>= 1 s = 0 while len(self.l_queue) > 0: l = self.l_queue.popleft() s *= self.pow_b[self.weights[l]] s %= H s += self.array[l] s %= H while len(self.r_queue) > 0: l = self.r_queue.popleft() s *= self.pow_b[self.weights[l]] s %= H s += self.array[l] s %= H return s def main(): N, L, Q = map(int, input().split()) S = [] for _ in range(N): S.append(input()) queries = [] for _ in range(Q): values = input().split() queries.append(values) # 下準備 pow_b = [0] * (L + 1) b = 1 for i in range(L + 1): pow_b[i] = b b *= B b %= H # 下準備2 s_arrays = [] segs = [] for i in range(N): s_array = [ord(s) - ord("a") + 1 for s in S[i]] s_arrays.append(s_array) seg = SegmentTree(s_array, pow_b) segs.append(seg) for values in queries: if values[0] == "1": _, k, c, d = values k = int(k) - 1 c = ord(c) - ord("a") + 1 d = ord(d) - ord("a") + 1 for i in range(N): if s_arrays[i][k] == c: s_arrays[i][k] = d segs[i].set(k, d) elif values[0] == "2": _, t = values t_hash = 0 for t0 in t: t_hash *= B t_hash %= H t_hash += ord(t0) - ord("a") + 1 t_hash %= H t_len = len(t) answer = 0 for i in range(N): x = segs[i].get_sum(0, t_len) if t_hash == x: answer += 1 print(answer) if __name__ == "__main__": main()