結果
問題 | No.2761 Substitute and Search |
ユーザー | magurofly |
提出日時 | 2024-05-06 00:01:42 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 560 ms / 4,000 ms |
コード長 | 3,157 bytes |
コンパイル時間 | 13,638 ms |
コンパイル使用メモリ | 398,848 KB |
実行使用メモリ | 354,816 KB |
最終ジャッジ日時 | 2024-11-29 18:27:27 |
合計ジャッジ時間 | 18,214 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,248 KB |
testcase_03 | AC | 1 ms
5,248 KB |
testcase_04 | AC | 469 ms
33,152 KB |
testcase_05 | AC | 60 ms
21,632 KB |
testcase_06 | AC | 195 ms
349,184 KB |
testcase_07 | AC | 560 ms
354,688 KB |
testcase_08 | AC | 64 ms
29,824 KB |
testcase_09 | AC | 297 ms
35,540 KB |
testcase_10 | AC | 194 ms
349,120 KB |
testcase_11 | AC | 229 ms
354,816 KB |
testcase_12 | AC | 235 ms
351,968 KB |
testcase_13 | AC | 234 ms
351,872 KB |
testcase_14 | AC | 92 ms
32,640 KB |
testcase_15 | AC | 212 ms
352,000 KB |
ソースコード
use proconio::{input, marker::{Chars, Usize1}}; use std::num::*; struct TrieNode { pub children: [Option<NonZeroU32>; 26], pub sum: usize, } impl TrieNode { pub fn new() -> Self { Self { children: [None; 26], sum: 0, } } } struct Trie { nodes: Vec<TrieNode>, subst: Vec<Vec<Vec<u8>>>, } impl Trie { pub fn new(l: usize) -> Self { Self { nodes: vec![TrieNode::new()], subst: vec![(0 .. 26).map(|i| vec![i] ).collect(); l], } } pub fn add(&mut self, s: &[usize]) { let mut cur = 0; self.nodes[cur].sum += 1; for k in 0 .. s.len() { let c = s[k]; if self.nodes[cur].children[c].is_none() { let id = self.nodes.len(); self.nodes.push(TrieNode::new()); self.nodes[cur].children[c] = NonZeroU32::new(id as u32); } cur = self.nodes[cur].children[c].unwrap().get() as usize; self.nodes[cur].sum += 1; } } pub fn substitute(&mut self, k: usize, c: usize, d: usize) { let mut src = std::mem::take(&mut self.subst[k][c]); self.subst[k][d].append(&mut src); } pub fn search(&mut self, s: &[usize]) -> usize { let mut cur = 0; for k in 0 .. s.len() { let d = s[k]; let mut next = None; for c in self.subst[k][d].clone() { if let Some(id) = self.nodes[cur].children[c as usize] { if let Some(next_id) = next { self.merge(next_id, id.get() as usize); self.nodes[cur].children[c as usize] = None; } else { next = Some(id.get() as usize); } } } if let Some(id) = next { cur = id; } else { return 0; } } self.nodes[cur].sum } fn merge(&mut self, dst: usize, src: usize) { self.nodes[dst].sum += self.nodes[src].sum; for c in 0 .. 26 { if let Some(src_child) = self.nodes[src].children[c] { if let Some(dst_child) = self.nodes[dst].children[c] { self.merge(dst_child.get() as usize, src_child.get() as usize); } else { self.nodes[dst].children[c] = Some(src_child); } } } } } fn convert(s: &[char]) -> Vec<usize> { s.iter().map(|&c| (c as u8 - b'a') as usize ).collect() } fn main() { input! { n: usize, l: usize, q: usize, strs: [Chars; n], } let mut trie = Trie::new(l); for s in strs { trie.add(&convert(&s)); } for _ in 0 .. q { input!(qtype: usize); if qtype == 1 { input!(k: Usize1, c: char, d: char); trie.substitute(k, (c as u8 - b'a') as usize, (d as u8 - b'a') as usize); } else { input!(t: Chars); let ans = trie.search(&convert(&t)); println!("{ans}"); } } }