結果

問題 No.449 ゆきこーだーの雨と雪 (4)
ユーザー ngtkanangtkana
提出日時 2023-11-06 01:31:30
言語 Rust
(1.77.0 + proconio)
結果
AC  
実行時間 202 ms / 5,000 ms
コード長 29,589 bytes
コンパイル時間 22,301 ms
コンパイル使用メモリ 380,456 KB
実行使用メモリ 18,172 KB
最終ジャッジ日時 2024-09-25 22:57:04
合計ジャッジ時間 25,705 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,248 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 1 ms
5,376 KB
testcase_11 AC 2 ms
5,376 KB
testcase_12 AC 131 ms
8,428 KB
testcase_13 AC 179 ms
12,212 KB
testcase_14 AC 202 ms
12,080 KB
testcase_15 AC 157 ms
12,048 KB
testcase_16 AC 182 ms
12,028 KB
testcase_17 AC 183 ms
12,056 KB
testcase_18 AC 128 ms
8,380 KB
testcase_19 AC 197 ms
12,060 KB
testcase_20 AC 198 ms
12,152 KB
testcase_21 AC 174 ms
12,024 KB
testcase_22 AC 175 ms
12,076 KB
testcase_23 AC 131 ms
8,404 KB
testcase_24 AC 186 ms
12,056 KB
testcase_25 AC 147 ms
8,320 KB
testcase_26 AC 164 ms
8,320 KB
testcase_27 AC 171 ms
12,156 KB
testcase_28 AC 175 ms
12,052 KB
testcase_29 AC 195 ms
12,028 KB
testcase_30 AC 160 ms
12,056 KB
testcase_31 AC 173 ms
12,088 KB
testcase_32 AC 192 ms
12,084 KB
testcase_33 AC 181 ms
12,088 KB
testcase_34 AC 148 ms
8,448 KB
testcase_35 AC 159 ms
12,092 KB
testcase_36 AC 148 ms
8,448 KB
testcase_37 AC 152 ms
18,172 KB
testcase_38 AC 163 ms
13,116 KB
testcase_39 AC 153 ms
13,108 KB
testcase_40 AC 160 ms
13,112 KB
testcase_41 AC 117 ms
13,112 KB
testcase_42 AC 118 ms
13,112 KB
testcase_43 AC 129 ms
8,448 KB
testcase_44 AC 80 ms
8,436 KB
testcase_45 AC 150 ms
18,168 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: unused import: `map::Multimap`
   --> src/main.rs:808:13
    |
808 |     pub use map::Multimap;
    |             ^^^^^^^^^^^^^
    |
    = note: `#[warn(unused_imports)]` on by default

warning: unused import: `map::Segmap`
   --> src/main.rs:810:13
    |
810 |     pub use map::Segmap;
    |             ^^^^^^^^^^^

warning: unused import: `map::SegmapOp`
   --> src/main.rs:811:13
    |
811 |     pub use map::SegmapOp;
    |             ^^^^^^^^^^^^^

ソースコード

diff #

use input::input;
use input::input_array;
use input::input_vec;
use std::cmp::Reverse;
use std::collections::HashMap;

fn main() {
    let _ = input::<usize>();
    let a = input_vec::<u64>();
    let q = input::<usize>();
    let queries = std::iter::repeat_with(|| {
        let [name, p] = input_array::<String, 2>();
        (name, p.parse::<char>().unwrap())
    })
    .take(q)
    .collect::<Vec<_>>();
    let mut name_id = HashMap::new();
    for (name, _) in &queries {
        let len = name_id.len();
        name_id.entry(name).or_insert(len);
    }
    let n = name_id.len();

    // (Reverse(score), time)
    let mut map = rb::Multiset::new();
    let mut keys = vec![(Reverse(0), 0); n];
    let mut solved = vec![0; a.len()];
    for i in 0..n {
        map.insert(keys[i]);
    }
    let mut time = 0;
    for &(ref name, p) in &queries {
        let mut key = keys[name_id[name]];
        if p == '?' {
            println!("{}", map.binary_search(&key).unwrap() + 1);
        } else {
            let p = (p as u8 - b'A') as usize;
            let (Reverse(score), _time) = map.remove(&key).unwrap();
            key = (
                Reverse(score + 50 * a[p] + 250 * a[p] / (5 + solved[p as usize])),
                time,
            );
            solved[p as usize] += 1;
            keys[name_id[name]] = key;
            map.insert(key);
            time += 1;
        }
    }
}

// input {{{
#[allow(dead_code)]
mod input {
    use std::cell::Cell;
    use std::convert::TryFrom;
    use std::io::stdin;
    use std::io::BufRead;
    use std::io::BufReader;
    use std::io::Lines;
    use std::io::Stdin;
    use std::str::FromStr;
    use std::sync::Mutex;
    use std::sync::Once;
    type Server = Mutex<Lines<BufReader<Stdin>>>;
    static ONCE: Once = Once::new();
    pub struct Lazy(Cell<Option<Server>>);
    unsafe impl Sync for Lazy {}
    fn line() -> String {
        static SYNCER: Lazy = Lazy(Cell::new(None));
        ONCE.call_once(|| {
            SYNCER
                .0
                .set(Some(Mutex::new(BufReader::new(stdin()).lines())));
        });
        unsafe {
            (*SYNCER.0.as_ptr())
                .as_ref()
                .unwrap()
                .lock()
                .unwrap()
                .next()
                .unwrap()
                .unwrap()
        }
    }
    pub trait ForceFromStr: FromStr {
        fn force_from_str(s: &str) -> Self;
    }
    impl<T, E> ForceFromStr for T
    where
        T: FromStr<Err = E>,
        E: std::fmt::Debug,
    {
        fn force_from_str(s: &str) -> Self { s.parse().unwrap() }
    }
    pub fn input_array<T: ForceFromStr, const N: usize>() -> [T; N]
    where
        T: std::fmt::Debug,
    {
        <[_; N]>::try_from(input_vec()).unwrap()
    }
    pub fn input_vec<T: ForceFromStr>() -> Vec<T> {
        line()
            .split_whitespace()
            .map(T::force_from_str)
            .collect::<Vec<_>>()
    }
    pub fn input<T: ForceFromStr>() -> T { T::force_from_str(&line()) }
}
// }}}
// rb {{{
#[allow(dead_code)]
mod rb {
    mod balance {
        use core::fmt;
        use std::ops::Deref;
        use std::ops::DerefMut;
        use std::ptr::NonNull;
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
        pub enum Color {
            Red,
            Black,
        }
        pub trait Balance: Sized {
            fn update(&mut self);
            fn push(&mut self);
            fn color(&mut self) -> &mut Color;
            fn parent(&mut self) -> &mut Option<Ptr<Self>>;
            fn left(&mut self) -> &mut Option<Ptr<Self>>;
            fn right(&mut self) -> &mut Option<Ptr<Self>>;
        }
        pub struct Tree<T: Balance> {
            pub root: Option<Ptr<T>>,
            pub black_height: u8,
        }
        impl<T: Balance> Tree<T> {
            pub fn new() -> Self {
                Self {
                    root: None,
                    black_height: 0,
                }
            }

            // Updates: the proper ancestors of `x` (i.e. `x` should be already updated)
            pub fn fix_red(&mut self, mut x: Ptr<T>) {
                while color(*x.parent()) == Color::Red {
                    let mut p = x.parent().unwrap();
                    let Some(mut pp) = p.parent() else {
                        p.update();
                        *p.color() = Color::Black;
                        self.black_height += 1;
                        return;
                    };
                    // Case 1: `p` is the left child.
                    if *pp.left() == Some(p) {
                        // Case 1.1: `pp` is a 5-node.
                        if color(*pp.right()) == Color::Red {
                            *p.color() = Color::Black;
                            *pp.color() = Color::Red;
                            *pp.right().unwrap().color() = Color::Black;
                            p.update();
                            pp.update();
                            x = pp;
                        }
                        // Case 1.2: `pp` is a splayed 4-node.
                        else if *p.right() == Some(x) {
                            rotate_left(p);
                            rotate_right(pp);
                            *x.color() = Color::Black;
                            *pp.color() = Color::Red;
                            p.update();
                            pp.update();
                            x.update();
                            break;
                        }
                        // Case 1.3: `pp` is a straight 4-node.
                        else {
                            rotate_right(pp);
                            *p.color() = Color::Black;
                            *pp.color() = Color::Red;
                            pp.update();
                            break;
                        }
                    }
                    // Case 2: `p` is the right child.
                    else {
                        // Case 2.1: `pp` is a 5-node.
                        if color(*pp.left()) == Color::Red {
                            *p.color() = Color::Black;
                            *pp.color() = Color::Red;
                            *pp.left().unwrap().color() = Color::Black;
                            p.update();
                            pp.update();
                            x = pp;
                        }
                        // Case 2.2: `pp` is a splayed 4-node.
                        else if *p.left() == Some(x) {
                            rotate_right(p);
                            rotate_left(pp);
                            *x.color() = Color::Black;
                            *pp.color() = Color::Red;
                            p.update();
                            pp.update();
                            x.update();
                            break;
                        }
                        // Case 2.3: `pp` is a straight 4-node.
                        else {
                            rotate_left(pp);
                            *p.color() = Color::Black;
                            *pp.color() = Color::Red;
                            pp.update();
                            break;
                        }
                    }
                }
                self.root = Some(x.update_ancestors());
            }

            // Updates: the proper ancestors of `x` (i.e. `x` should be already updated)
            pub fn fix_black(&mut self, black_violation: BlackViolation<T>) {
                let BlackViolation { p, mut x } = black_violation;
                loop {
                    if color(x) == Color::Red {
                        *x.unwrap().color() = Color::Black;
                        break;
                    }
                    let p = x.map_or(p, |mut x| *x.parent());
                    let Some(mut p) = p else {
                        self.black_height -= 1;
                        return;
                    };
                    // Case 1: `x` is the left child.
                    if *p.left() == x {
                        let mut s = p.right().unwrap();
                        if *s.color() == Color::Red {
                            rotate_left(p);
                            *p.color() = Color::Red;
                            *s.color() = Color::Black;
                            s = p.right().unwrap();
                        }
                        match (color(*s.left()), color(*s.right())) {
                            // Case 1.1: `s` is a 2-node.
                            (Color::Black, Color::Black) => {
                                *s.color() = Color::Red;
                                p.update();
                                x = Some(p);
                            }
                            // Case 1.2: `s` is a left-leaning 3-node.
                            (Color::Red, Color::Black) => {
                                let mut c = s.left().unwrap();
                                rotate_right(s);
                                rotate_left(p);
                                *c.color() = *p.color();
                                *p.color() = Color::Black;
                                s.update();
                                break;
                            }
                            // Case 1.3: `s` is a right-leaning 3-node, or a 4-node.
                            (_, Color::Red) => {
                                rotate_left(p);
                                *s.color() = *p.color();
                                *p.color() = Color::Black;
                                *s.right().unwrap().color() = Color::Black;
                                break;
                            }
                        }
                    }
                    // Case 2: `x` is the right child.
                    else {
                        let mut s = p.left().unwrap();
                        if *s.color() == Color::Red {
                            rotate_right(p);
                            *p.color() = Color::Red;
                            *s.color() = Color::Black;
                            s = p.left().unwrap();
                        }
                        match (color(*s.left()), color(*s.right())) {
                            // Case 2.1: `s` is a 2-node.
                            (Color::Black, Color::Black) => {
                                *s.color() = Color::Red;
                                p.update();
                                x = Some(p);
                            }
                            // Case 2.2: `s` os a right-leaning 3-node.
                            (Color::Black, Color::Red) => {
                                let mut c = s.right().unwrap();
                                rotate_left(s);
                                rotate_right(p);
                                *c.color() = *p.color();
                                *p.color() = Color::Black;
                                s.update();
                                break;
                            }
                            // Case 2.3: `s` is a left-leaning 3-node, or a 4-node.
                            (Color::Red, _) => {
                                rotate_right(p);
                                *s.color() = *p.color();
                                *p.color() = Color::Black;
                                *s.left().unwrap().color() = Color::Black;
                                break;
                            }
                        }
                    }
                }
                self.root = Some(match x {
                    None => {
                        p.unwrap().update();
                        p.unwrap().update_ancestors()
                    }
                    Some(x) => x.update_ancestors(),
                })
            }

            pub fn transplant(&mut self, mut place: Ptr<T>, new: Option<Ptr<T>>) {
                if let Some(mut p) = *place.parent() {
                    *(if *p.left() == Some(place) { p.left() } else { p.right() }) = new;
                } else {
                    self.root = new;
                }
                if let Some(mut new) = new {
                    *new.parent() = *place.parent();
                }
            }
        }
        pub struct BlackViolation<T: Balance> {
            pub p: Option<Ptr<T>>,
            pub x: Option<Ptr<T>>,
        }
        impl<T: Balance> PartialEq for BlackViolation<T> {
            fn eq(&self, other: &Self) -> bool { (self.p, self.x) == (other.p, other.x) }
        }
        impl<T: Balance> fmt::Debug for BlackViolation<T> {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                f.debug_struct("BlackViolation")
                    .field("p", &self.p)
                    .field("x", &self.x)
                    .finish()
            }
        }
        impl<T: Balance> Clone for BlackViolation<T> {
            fn clone(&self) -> Self {
                Self {
                    p: self.p,
                    x: self.x,
                }
            }
        }
        impl<T: Balance> Copy for BlackViolation<T> {}
        fn color<T: Balance>(x: Option<Ptr<T>>) -> Color {
            match x {
                None => Color::Black,
                Some(mut x) => *x.color(),
            }
        }
        fn rotate_left<T: Balance>(mut l: Ptr<T>) {
            let p = *l.parent();
            let mut r = l.right().unwrap();
            let c = *r.left();
            // Connect `p` and `r`.
            *r.parent() = p;
            if let Some(mut p) = p {
                *(if *p.left() == Some(l) { p.left() } else { p.right() }) = Some(r);
            }
            // Connect `r` and `l`.
            *l.parent() = Some(r);
            *r.left() = Some(l);
            // Connect `l` and `c`.
            if let Some(mut c) = c {
                *c.parent() = Some(l);
            }
            *l.right() = c;
        }
        fn rotate_right<T: Balance>(mut r: Ptr<T>) {
            let p = *r.parent();
            let mut l = r.left().unwrap();
            let c = *l.right();
            // Connect `p` and `l`.
            *l.parent() = p;
            if let Some(mut p) = p {
                *(if *p.left() == Some(r) { p.left() } else { p.right() }) = Some(l);
            }
            // Connect `l` and `r`.
            *r.parent() = Some(l);
            *l.right() = Some(r);
            // Connect `r` and `c`.
            if let Some(mut c) = c {
                *c.parent() = Some(r);
            }
            *r.left() = c;
        }
        pub struct Ptr<T>(NonNull<T>);
        impl<T: Balance> Ptr<T> {
            pub fn new(x: T) -> Self { Self(NonNull::from(Box::leak(Box::new(x)))) }

            pub fn free(self) -> T { unsafe { *Box::from_raw(self.0.as_ptr()) } }

            // Returns the root
            pub fn update_ancestors(self) -> Self {
                let mut x = self;
                while let Some(mut p) = *x.parent() {
                    p.update();
                    x = p;
                }
                x
            }

            pub fn as_longlife_ref<'a>(self) -> &'a T { unsafe { self.0.as_ref() } }

            pub fn as_longlife_mut<'a>(mut self) -> &'a mut T { unsafe { self.0.as_mut() } }
        }
        impl<T> Clone for Ptr<T> {
            fn clone(&self) -> Self { *self }
        }
        impl<T> Copy for Ptr<T> {}
        impl<T> Deref for Ptr<T> {
            type Target = T;

            fn deref(&self) -> &Self::Target { unsafe { self.0.as_ref() } }
        }
        impl<T> DerefMut for Ptr<T> {
            fn deref_mut(&mut self) -> &mut Self::Target { unsafe { self.0.as_mut() } }
        }
        impl<T> fmt::Debug for Ptr<T> {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{:02x}", self.0.as_ptr() as usize % 0x1000 / 0x10)
            }
        }
        impl<T> PartialEq for Ptr<T> {
            fn eq(&self, other: &Self) -> bool { std::ptr::eq(self.0.as_ptr(), other.0.as_ptr()) }
        }
    }
    mod map {
        use crate::rb::balance::Balance;
        use crate::rb::balance::BlackViolation;
        use crate::rb::balance::Color;
        use crate::rb::balance::Ptr;
        use crate::rb::balance::Tree;
        use std::borrow::Borrow;
        use std::cmp::Ordering;
        use std::marker::PhantomData;
        pub trait SegmapOp {
            type Value;
            type Acc;
            type Lazy: PartialEq;
            fn to_acc(value: &Self::Value) -> Self::Acc;
            fn join(
                lhs: Option<&Self::Acc>,
                center: &Self::Value,
                rhs: Option<&Self::Acc>,
            ) -> Self::Acc;
            fn apply(_value: &mut Self::Value, _lazy: &Self::Lazy);
            fn compose(_lhs: &Self::Lazy, _rhs: &Self::Lazy) -> Self::Lazy;
            fn identity() -> Self::Lazy;
            fn is_identity(lazy: &Self::Lazy) -> bool { *lazy == Self::identity() }
        }
        #[allow(dead_code)]
        pub struct Node<K, O: SegmapOp> {
            key: K,
            value: O::Value,
            acc: O::Acc,
            lazy: O::Lazy,
            parent: Option<Ptr<Node<K, O>>>,
            left: Option<Ptr<Node<K, O>>>,
            right: Option<Ptr<Node<K, O>>>,
            len: usize,
            color: Color,
        }
        impl<K: Ord, O: SegmapOp> Node<K, O> {
            pub fn new(key: K, value: O::Value, color: Color) -> Self {
                Self {
                    key,
                    acc: O::to_acc(&value),
                    value,
                    lazy: O::identity(),
                    parent: None,
                    left: None,
                    right: None,
                    len: 1,
                    color,
                }
            }
        }
        fn len<K, O: SegmapOp>(node: Option<Ptr<Node<K, O>>>) -> usize {
            node.as_ref().map_or(0, |node| node.len)
        }
        fn acc<K, O: SegmapOp>(node: &Option<Ptr<Node<K, O>>>) -> Option<&O::Acc> {
            node.as_ref().map(|node| &node.acc)
        }
        impl<K, O: SegmapOp> Balance for Node<K, O> {
            fn update(&mut self) {
                self.len = len(self.left) + 1 + len(self.right);
                self.acc = O::join(acc(&self.left), &self.value, acc(&self.right));
            }

            fn push(&mut self) {}

            fn color(&mut self) -> &mut Color { &mut self.color }

            fn parent(&mut self) -> &mut Option<Ptr<Self>> { &mut self.parent }

            fn left(&mut self) -> &mut Option<Ptr<Self>> { &mut self.left }

            fn right(&mut self) -> &mut Option<Ptr<Self>> { &mut self.right }
        }
        pub struct Segmap<K, O: SegmapOp> {
            tree: Tree<Node<K, O>>,
        }
        impl<K: Ord, O: SegmapOp> Segmap<K, O> {
            pub fn new() -> Self { Self { tree: Tree::new() } }

            pub fn len(&self) -> usize { len(self.tree.root) }

            pub fn is_empty(&self) -> bool { self.tree.root.is_none() }

            pub fn nth(&self, n: usize) -> (&K, &O::Value) {
                let x = self.nth_ptr(n).as_longlife_ref();
                (&x.key, &x.value)
            }

            pub fn nth_mut(&mut self, n: usize) -> (&K, &mut O::Value) {
                let x = self.nth_ptr(n).as_longlife_mut();
                (&x.key, &mut x.value)
            }

            pub fn binary_search<Q: ?Sized>(&self, key: &Q) -> Option<&O::Value>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.binary_search_ptr(key)
                    .map(|(x, _)| &x.as_longlife_ref().value)
            }

            pub fn binary_search_index<Q: ?Sized>(&self, key: &Q) -> Option<usize>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.binary_search_ptr(key).map(|(_, i)| i)
            }

            pub fn insert(&mut self, key: K, value: O::Value) {
                let mut new = Ptr::new(Node::new(key, value, Color::Red));
                let Some(mut x) = self.tree.root else {
                    new.color = Color::Black;
                    self.tree.root = Some(new);
                    self.tree.black_height = 1;
                    return;
                };
                let key = &new.key;
                loop {
                    match key.cmp(&x.key) {
                        Ordering::Less | Ordering::Equal => {
                            if let Some(left) = x.left {
                                x = left;
                            } else {
                                new.parent = Some(x);
                                x.left = Some(new);
                                break;
                            }
                        }
                        Ordering::Greater => {
                            if let Some(right) = x.right {
                                x = right;
                            } else {
                                new.parent = Some(x);
                                x.right = Some(new);
                                break;
                            }
                        }
                    }
                }
                if x.color == Color::Red {
                    self.tree.fix_red(new);
                } else {
                    new.update_ancestors();
                }
            }

            pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, O::Value)>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                let x = self.binary_search_ptr(key)?.0;
                self.remove_ptr(x);
                let x = x.free();
                Some((x.key, x.value))
            }

            pub fn remove_nth(&mut self, n: usize) -> (K, O::Value) {
                let x = self.nth_ptr(n);
                self.remove_ptr(x);
                let x = x.free();
                (x.key, x.value)
            }

            fn nth_ptr(&self, mut n: usize) -> Ptr<Node<K, O>> {
                assert!(
                    n < self.len(),
                    "Index out of range: n = {n}, while len = {}",
                    self.len()
                );
                let mut x = self.tree.root.unwrap();
                loop {
                    let left_len = len(x.left);
                    x = match n.cmp(&left_len) {
                        Ordering::Less => x.left.unwrap(),
                        Ordering::Equal => break,
                        Ordering::Greater => {
                            n -= left_len + 1;
                            x.right.unwrap()
                        }
                    };
                }
                x
            }

            pub fn binary_search_ptr<Q: ?Sized>(&self, key: &Q) -> Option<(Ptr<Node<K, O>>, usize)>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                let mut x = self.tree.root?;
                let mut index = 0;
                loop {
                    x = match key.cmp(x.key.borrow()) {
                        Ordering::Less => x.left?,
                        Ordering::Greater => {
                            index += len(x.left) + 1;
                            x.right?
                        }
                        Ordering::Equal => break,
                    }
                }
                Some((x, index + len(x.left)))
            }

            fn remove_ptr(&mut self, x: Ptr<Node<K, O>>) {
                let needs_fix;
                let black_vio;
                match (x.left, x.right) {
                    (Some(_), Some(top)) => {
                        let mut next = top;
                        while let Some(left) = next.left {
                            next = left;
                        }
                        needs_fix = next.color == Color::Black;
                        next.left = x.left;
                        x.left.unwrap().parent = Some(next);
                        next.color = x.color;
                        if top == next {
                            black_vio = BlackViolation {
                                p: Some(next),
                                x: next.right,
                            };
                            self.tree.transplant(x, Some(next));
                        } else {
                            black_vio = BlackViolation {
                                p: next.parent,
                                x: next.right,
                            };
                            self.tree.transplant(next, next.right);
                            next.right = x.right;
                            if let Some(mut r) = next.right {
                                r.parent = Some(next);
                            }
                            self.tree.transplant(x, Some(next));
                        }
                    }
                    (None, Some(_)) => {
                        needs_fix = x.color == Color::Black;
                        black_vio = BlackViolation {
                            p: x.parent,
                            x: x.right,
                        };
                        self.tree.transplant(x, x.right);
                    }
                    (_, None) => {
                        needs_fix = x.color == Color::Black;
                        black_vio = BlackViolation {
                            p: x.parent,
                            x: x.left,
                        };
                        self.tree.transplant(x, x.left);
                    }
                }
                if needs_fix {
                    self.tree.fix_black(black_vio);
                } else if let Some(mut p) = black_vio.p {
                    p.update();
                    p.update_ancestors();
                }
            }
        }
        impl<K: Ord, O: SegmapOp> Default for Segmap<K, O> {
            fn default() -> Self { Self::new() }
        }
        struct Nop<T>(PhantomData<T>);
        impl<T> SegmapOp for Nop<T> {
            type Acc = ();
            type Lazy = ();
            type Value = T;

            fn to_acc(_value: &Self::Value) -> Self::Acc {}

            fn join(
                _lhs: Option<&Self::Acc>,
                _center: &Self::Value,
                _rhs: Option<&Self::Acc>,
            ) -> Self::Acc {
            }

            fn apply(_value: &mut Self::Value, _lazy: &Self::Lazy) {}

            fn compose(_lhs: &Self::Lazy, _rhs: &Self::Lazy) -> Self::Lazy {}

            fn identity() -> Self::Lazy {}
        }
        pub struct Multimap<K, V> {
            segmap: Segmap<K, Nop<V>>,
        }
        impl<K: Ord, V> Multimap<K, V> {
            pub fn new() -> Self {
                Self {
                    segmap: Segmap::new(),
                }
            }

            pub fn len(&self) -> usize { self.segmap.len() }

            pub fn is_empty(&self) -> bool { self.segmap.is_empty() }

            pub fn nth(&self, n: usize) -> (&K, &V) { self.segmap.nth(n) }

            pub fn binary_search<Q: ?Sized>(&self, key: &Q) -> Option<&V>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.segmap.binary_search(key)
            }

            pub fn binary_search_index<Q: ?Sized>(&self, key: &Q) -> Option<usize>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.segmap.binary_search_index(key)
            }

            pub fn insert(&mut self, key: K, value: V) { self.segmap.insert(key, value) }

            pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.segmap.remove(key)
            }

            pub fn remove_nth(&mut self, n: usize) -> (K, V) { self.segmap.remove_nth(n) }
        }
        impl<K: Ord, V> Default for Multimap<K, V> {
            fn default() -> Self { Self::new() }
        }
        pub struct Multiset<K> {
            map: Multimap<K, ()>,
        }
        impl<K: Ord> Multiset<K> {
            pub fn new() -> Self {
                Self {
                    map: Multimap::new(),
                }
            }

            pub fn len(&self) -> usize { self.map.len() }

            pub fn is_empty(&self) -> bool { self.map.is_empty() }

            pub fn nth(&self, n: usize) -> &K { self.map.nth(n).0 }

            pub fn binary_search<Q: ?Sized>(&self, key: &Q) -> Option<usize>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.map.binary_search_index(key)
            }

            pub fn insert(&mut self, key: K) { self.map.insert(key, ()) }

            pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<K>
            where
                K: Ord + Borrow<Q>,
                Q: Ord,
            {
                self.map.remove(key).map(|(k, _)| k)
            }

            pub fn remove_nth(&mut self, n: usize) -> K { self.map.remove_nth(n).0 }
        }
        impl<K: Ord> Default for Multiset<K> {
            fn default() -> Self { Self::new() }
        }
    }
    pub use map::Multimap;
    pub use map::Multiset;
    pub use map::Segmap;
    pub use map::SegmapOp;
}
// }}}
0