結果

問題 No.2761 Substitute and Search
ユーザー maguroflymagurofly
提出日時 2024-05-05 23:56:10
言語 Rust
(1.77.0)
結果
MLE  
実行時間 -
コード長 3,027 bytes
コンパイル時間 12,511 ms
コンパイル使用メモリ 401,944 KB
実行使用メモリ 808,972 KB
最終ジャッジ日時 2024-05-07 04:54:10
合計ジャッジ時間 15,248 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 1 ms
6,816 KB
testcase_02 AC 1 ms
6,940 KB
testcase_03 AC 0 ms
6,940 KB
testcase_04 AC 507 ms
34,320 KB
testcase_05 AC 66 ms
22,912 KB
testcase_06 MLE -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

use proconio::{input, marker::{Chars, Usize1}};

struct TrieNode {
    pub children: [Option<usize>; 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<usize>>>,
}
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] = Some(id);
            }
            cur = self.nodes[cur].children[c].unwrap();
            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] {
                    if let Some(next_id) = next {
                        self.merge(next_id, id);
                        self.nodes[cur].children[c] = None;
                    } else {
                        next = Some(id);
                    }
                }
            }
            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, src_child);
                } 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}");
        }
    }
}
0