Submission #18834680


Source Code Expand

use std::collections::BTreeMap;

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    let n: usize = sc.read();
    let q: usize = sc.read();
    let c: Vec<usize> = sc.vec(n);
    let mut uf = UnionFind::new(&c);
    for _ in 0..q {
        let t: usize = sc.read();
        if t == 1 {
            let a = sc.read::<usize>() - 1;
            let b = sc.read::<usize>() - 1;
            uf.unite(a, b);
        } else {
            let x = sc.read::<usize>() - 1;
            let y = sc.read::<usize>();
            let root = uf.find(x);
            let ans = uf.sizes[root]
                .as_ref()
                .unwrap()
                .get(&y)
                .cloned()
                .unwrap_or(0);
            sc.write(ans);
            sc.write('\n');
        }
    }
}

pub struct UnionFind {
    parent: Vec<usize>,
    sizes: Vec<Option<BTreeMap<usize, usize>>>,
    size: usize,
}

impl UnionFind {
    pub fn new(c: &[usize]) -> UnionFind {
        let n = c.len();
        let mut sizes = vec![Some(BTreeMap::new()); n];
        for i in 0..n {
            sizes[i].as_mut().unwrap().insert(c[i], 1);
        }
        UnionFind {
            parent: (0..n).map(|i| i).collect::<Vec<usize>>(),
            sizes,
            size: n,
        }
    }

    pub fn find(&mut self, x: usize) -> usize {
        if x == self.parent[x] {
            x
        } else {
            let px = self.parent[x];
            self.parent[x] = self.find(px);
            self.parent[x]
        }
    }

    pub fn unite(&mut self, x: usize, y: usize) -> bool {
        let parent_x = self.find(x);
        let parent_y = self.find(y);
        if parent_x == parent_y {
            return false;
        }

        let (large, small) = if self.sizes[parent_x].as_ref().unwrap().len()
            < self.sizes[parent_y].as_ref().unwrap().len()
        {
            (parent_y, parent_x)
        } else {
            (parent_x, parent_y)
        };

        self.parent[small] = large;
        let small_sizes = self.sizes[small].take().unwrap();
        for (color, count) in small_sizes {
            *self.sizes[large]
                .as_mut()
                .unwrap()
                .entry(color)
                .or_insert(0) += count;
        }

        self.size -= 1;
        true
    }
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        Self(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write_all(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

Submission Info

Submission Time
Task F - Confluence
User kenkoooo
Language Rust (1.42.0)
Score 600
Code Size 3591 Byte
Status AC
Exec Time 270 ms
Memory 50348 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 600 / 600
Status
AC × 3
AC × 21
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All path_01.txt, path_02.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_11.txt, random_12.txt, random_13.txt, random_21.txt, random_22.txt, random_23.txt, sample_01.txt, sample_02.txt, sample_03.txt, special_01.txt, special_02.txt
Case Name Status Exec Time Memory
path_01.txt AC 215 ms 47876 KiB
path_02.txt AC 151 ms 47920 KiB
random_01.txt AC 75 ms 2240 KiB
random_02.txt AC 83 ms 2228 KiB
random_03.txt AC 55 ms 2152 KiB
random_04.txt AC 74 ms 2100 KiB
random_05.txt AC 259 ms 50304 KiB
random_06.txt AC 221 ms 50348 KiB
random_07.txt AC 224 ms 50244 KiB
random_08.txt AC 191 ms 50320 KiB
random_11.txt AC 241 ms 50288 KiB
random_12.txt AC 206 ms 50200 KiB
random_13.txt AC 206 ms 50304 KiB
random_21.txt AC 226 ms 50280 KiB
random_22.txt AC 270 ms 50292 KiB
random_23.txt AC 226 ms 50296 KiB
sample_01.txt AC 1 ms 2040 KiB
sample_02.txt AC 1 ms 2052 KiB
sample_03.txt AC 1 ms 2080 KiB
special_01.txt AC 210 ms 33496 KiB
special_02.txt AC 117 ms 33788 KiB