summaryrefslogtreecommitdiff
path: root/kattis-open-almostunionfind/src/main.rs
diff options
context:
space:
mode:
authormathiasmagnusson <mathiasmagnussons@gmail.com>2022-12-09 18:00:41 +0100
committermathiasmagnusson <mathiasmagnussons@gmail.com>2022-12-09 18:00:41 +0100
commita1eb38bebe6ce1668c3f96489506c3b05b9fe5cb (patch)
treecccf0fd4763dba123efab7c896292dc18d1eb458 /kattis-open-almostunionfind/src/main.rs
parente41e6c8bc72e3300a0fa137f198454341bc315b1 (diff)
downloadprogramming-problem-solving-a1eb38bebe6ce1668c3f96489506c3b05b9fe5cb.tar.gz
Move stuff around
Diffstat (limited to 'kattis-open-almostunionfind/src/main.rs')
-rw-r--r--kattis-open-almostunionfind/src/main.rs153
1 files changed, 0 insertions, 153 deletions
diff --git a/kattis-open-almostunionfind/src/main.rs b/kattis-open-almostunionfind/src/main.rs
deleted file mode 100644
index 6563043..0000000
--- a/kattis-open-almostunionfind/src/main.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-// https://open.kattis.com/problems/almostunionfind
-
-use std::{
- io::{stdin, Read},
- iter::once,
-};
-
-enum Node {
- Root { count: u32, sum: u64 },
- Child(usize),
- Invalid,
-}
-
-impl Node {
- fn count(&self) -> u32 {
- match self {
- &Root { count, .. } => count,
- _ => unreachable!(),
- }
- }
-}
-
-use Node::*;
-
-fn root(uf: &mut [Node], mut node: usize) -> usize {
- let mut root = node;
- while let Child(parent) = uf[root] {
- root = parent
- }
- while let Child(parent) = uf[node] {
- uf[node] = Child(root);
- node = parent;
- }
- root
-}
-
-fn join(uf: &mut [Node], a: usize, b: usize) {
- let mut a = root(uf, a);
- let mut b = root(uf, b);
-
- if a == b {
- return;
- }
-
- if uf[a].count() < uf[b].count() {
- let tmp = a;
- a = b;
- b = tmp;
- }
-
- let (b_count, b_sum) = match uf[b] {
- Root { count, sum } => (count, sum),
- _ => unreachable!(),
- };
- match &mut uf[a] {
- Root { count, sum } => {
- *count += b_count;
- *sum += b_sum;
- }
- _ => unreachable!(),
- }
- uf[b] = Child(a);
-}
-
-fn mov(
- uf: &mut [Node],
- free_index: &mut usize,
- current_index_of: &mut [usize],
- a: usize,
- a_val: u64,
- b: usize,
-) {
- let a_root = root(uf, a);
- let b_root = root(uf, b);
- if a_root == b_root {
- return;
- }
- match &mut uf[a_root] {
- Root { count, sum } => {
- *count -= 1;
- *sum -= a_val;
- }
- _ => unreachable!(),
- }
- match &mut uf[b_root] {
- Root { count, sum } => {
- *count += 1;
- *sum += a_val;
- }
- _ => unreachable!(),
- }
- uf[*free_index] = Child(b_root);
- current_index_of[a_val as usize] = *free_index;
- *free_index += 1;
-}
-
-fn main() {
- let mut input = String::new();
- stdin().lock().read_to_string(&mut input).unwrap();
- let mut ints = input
- .trim()
- .split(|c| c == ' ' || c == '\n')
- .map(|i| i.parse::<usize>().unwrap());
- let mut get = || ints.next();
-
- while let Some(n) = get() {
- let m = get().unwrap();
-
- let mut uf: Vec<Node> = (0..n + m)
- .map(|i| {
- if i < n {
- Root {
- count: 1,
- sum: i as u64 + 1,
- }
- } else {
- Invalid
- }
- })
- .collect();
- let mut free_index = n;
- let mut current_index_of: Vec<usize> = (once(0).chain(0..n)).collect();
-
- for _ in 0..m {
- match get().unwrap() {
- 1 => {
- let (p, q) = (get().unwrap(), get().unwrap());
- join(&mut uf, current_index_of[p], current_index_of[q]);
- }
- 2 => {
- let (p, q) = (get().unwrap(), get().unwrap());
- let (pi, qi) = (current_index_of[p], current_index_of[q]);
- mov(
- &mut uf,
- &mut free_index,
- &mut current_index_of,
- pi,
- p as u64,
- qi,
- );
- }
- _ => {
- let p = get().unwrap();
- let r = root(&mut uf, current_index_of[p]);
- match uf[r] {
- Root { count, sum } => println!("{} {}", count, sum),
- _ => unreachable!(),
- }
- }
- }
- }
- }
-}