結果

問題 No.3298 K-th Slime
コンテスト
ユーザー hanba-gu1
提出日時 2025-10-05 16:17:41
言語 Rust
(1.94.0 + proconio + num + itertools)
コンパイル:
/usr/bin/rustc_custom
実行:
./target/release/main
結果
AC  
実行時間 399 ms / 2,000 ms
+ 661µs
コード長 13,659 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 6,838 ms
コンパイル使用メモリ 204,736 KB
実行使用メモリ 8,236 KB
最終ジャッジ日時 2026-07-15 13:48:59
合計ジャッジ時間 11,540 ms
ジャッジサーバーID
(参考情報)
judge1_0 / judge2_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 25
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: method `first` is never used
  --> src/main.rs:22:8
   |
14 | impl<T: Ord + Copy> BTreeMultiSet<T> {
   | ------------------------------------ method in this implementation
...
22 |     fn first(&self) -> Option<&T> {
   |        ^^^^^
   |
   = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default

ソースコード

diff #
raw source code

#![allow(unstable_name_collisions)]
use std::collections::BTreeMap;

use proconio::input;

#[allow(unused)]
use lib::*;

#[derive(Debug)]
struct BTreeMultiSet<T> {
    length: usize,
    counts: BTreeMap<T, usize>,
}
impl<T: Ord + Copy> BTreeMultiSet<T> {
    fn new() -> Self {
        Self { length: 0, counts: BTreeMap::new() }
    }
    fn insert(&mut self, value: T) {
        self.length += 1;
        *self.counts.entry(value).or_default() += 1;
    }
    fn first(&self) -> Option<&T> {
        self.counts.keys().next()
    }
    fn last(&self) -> Option<&T> {
        self.counts.keys().rev().next()
    }
    fn pop_first(&mut self) -> Option<T> {
        let mut count_entry = self.counts.first_entry()?;
        self.length -= 1;
        *count_entry.get_mut() -= 1;
        if *count_entry.get() == 0 {
            Some(count_entry.remove_entry().0)
        } else {
            Some(*count_entry.key())
        }
    }
    fn pop_last(&mut self) -> Option<T> {
        let mut count_entry = self.counts.last_entry()?;
        self.length -= 1;
        *count_entry.get_mut() -= 1;
        if *count_entry.get() == 0 {
            Some(count_entry.remove_entry().0)
        } else {
            Some(*count_entry.key())
        }
    }
}
impl<T: Ord + Copy> From<&[T]> for BTreeMultiSet<T> {
    fn from(value: &[T]) -> Self {
        let mut ret = Self::new();
        for v in value {
            ret.insert(*v);
        }
        ret
    }
}

fn main() {
    input! {
        n: usize, k: usize, q: usize,
        mut a: [i64; n],
    }
    a.sort();

    let mut less = BTreeMultiSet::from(&a[..k]);
    let mut greater = BTreeMultiSet::from(&a[k..]);

    for _ in 0..q {
        input! { query: u8 }
        match query {
            1 => {
                input! { x: i64 }
                less.insert(x);
                greater.insert(less.pop_last().unwrap());
            }
            2 => {
                input! { y: i64 }
                let temp = less.pop_last().unwrap();
                greater.insert(temp + y);
                less.insert(greater.pop_first().unwrap());
            }
            3 => {
                less.last().unwrap().println();
            }
            _ => {}
        }
    }
    less.dprintln();
    greater.dprintln();
}

#[allow(unused)]
mod lib {
    use std::{
        cmp::Ordering,
        fmt::{Debug, Display},
        marker::PhantomData,
    };
    use proconio::{input, source::Readable};

    #[macro_export]
    macro_rules! min {
        ($l:expr $(,)?) => { $l };
        ($l:expr, $($other:expr),+ $(,)?) => { std::cmp::min($l, min!($($other),*)) };
    }
    #[macro_export]
    macro_rules! max {
        ($l:expr $(,)?) => { $l };
        ($l:expr, $($other:expr),+ $(,)?) => { std::cmp::max($l, max!($($other),*)) };
    }
    #[macro_export]
    macro_rules! println_exit {
        ($($arg:tt)*) => {
            {
                println!($($arg)*);
                std::process::exit(0)
            }
        };
    }
    #[macro_export]
    macro_rules! all_eq {
        ($val:expr, $($vals:expr),*) => {
            $($val == $vals &&)* true
        };
    }
    #[macro_export]
    macro_rules! multi_vec {
        [$val:expr; $len:expr] => {
            vec![$val; $len]
        };
        [$val:expr; $len:expr, $($lens:expr),+] => {
            vec![multi_vec![$val; $($lens),+]; $len]
        };
    }
    #[macro_export]
    macro_rules! array {
        [$($val:expr),* $(,)?] => {
            [$($val),*]
        };
        [$val:expr; $len:expr] => {
            std::array::from_fn::<_, $len, _>(|_| $val.clone())
        };
    }
    #[macro_export]
    macro_rules! multi_array {
        [$val:expr; $len:expr] => {
            array![$val; $len]
        };
        [$val:expr; $len:expr, $($lens:expr),+] => {
            array![multi_array![$val; $($lens),+]; $len]
        };
    }
    #[macro_export]
    macro_rules! vec_deque {
        ($elem:expr; $len:expr) => {
            VecDeque::from(vec![$elem; $len])
        };
        ($($elem:expr),* $(,)?) => {
            VecDeque::from([$($elem),*])
        }
    }
    #[macro_export]
    macro_rules! cmp {
        ($_:tt) => { true };
        ($_0:tt, $_1:tt) => { true };
        ($l1:tt, $l2:tt $op:tt $r:tt $($others:tt)*) => {
            $l1 $op $r && $l2 $op $r && cmp!($r $($others)*)
        };
        ($l:tt $op:tt $r1:tt, $r2:tt $($others:tt)*) => {
            $l $op $r1 && $l $op $r2 && cmp!($r1, $r2 $($others)*)
        };
        ($l:tt $op:tt $r:tt $($others:tt)*) => {
            $l $op $r && cmp!($r $($others)*)
        };
    }
    #[macro_export]
    macro_rules! option_and_tuple {
        ($($opt:expr),* $(,)?) => {
            (|| Some(($($opt?),*)))()
        };
    }
    #[macro_export]
    macro_rules! swap {
        ($l:expr, $r:expr) => {
            ($l, $r) = ($r, $l)
        };
    }

    pub trait OrdAsign where Self: PartialOrd + Sized {
        fn chmax(&mut self, other: Self) -> bool {
            if other > *self { *self = other; true }
            else { false }
        }
        fn chmin(&mut self, other: Self) -> bool {
            if other < *self { *self = other; true }
            else { false }
        }
    }
    impl<T: PartialOrd + Sized> OrdAsign for T {}

    pub trait OptionExt<T> {
        fn insert_max(&mut self, other: T) -> bool where T: PartialOrd;
        fn insert_min(&mut self, other: T) -> bool where T: PartialOrd;
        fn tuple_and<U>(self, other: Option<U>) -> Option<(T, U)>;
    }
    impl<T> OptionExt<T> for Option<T> {
        fn insert_max(&mut self, other: T) -> bool where T: PartialOrd {
            match self {
                Some(s) => s.chmax(other),
                None => { *self = Some(other); true }
            }
        }
        fn insert_min(&mut self, other: T) -> bool where T: PartialOrd {
            match self {
                Some(s) => s.chmax(other),
                None => { *self = Some(other); true }
            }
        }
        fn tuple_and<U>(self, other: Option<U>) -> Option<(T, U)> {
            match (self, other) {
                (Some(s), Some(other)) => Some((s, other)),
                _ => None,
            }
        }
    }

    pub struct LenVec<T: Readable> { t: PhantomData<T> }
    impl<T: Readable> Readable for LenVec<T> {
        type Output = Vec<T::Output>;
        fn read<R: std::io::BufRead, S: proconio::source::Source<R>>(source: &mut S) -> Self::Output {
            input! {
                from source,
                len: usize,
                vec: [T; len],
            }
            vec
        }
    }

    pub trait BoolExt {
        fn yesno(&self) -> &'static str;
        fn print_yesno(&self);
        fn flip(&mut self);
    }
    impl BoolExt for bool {
        fn yesno(&self) -> &'static str { self.then_some("Yes").unwrap_or("No") }
        fn print_yesno(&self) { println!("{}", self.yesno()) }
        fn flip(&mut self) { *self = !*self }
    }

    pub trait Sorted<T: Ord>: Sized + AsMut<[T]> {
        fn sorted(mut self) -> Self {
            self.as_mut().sort();
            self
        }
        fn sorted_by(mut self, cmp: impl FnMut(&T, &T) -> Ordering) -> Self {
            self.as_mut().sort_by(cmp);
            self
        }
        fn sorted_by_key<K: Ord>(mut self, cmp: impl FnMut(&T) -> K) -> Self {
            self.as_mut().sort_by_key(cmp);
            self
        }
        fn rev_sorted(mut self) -> Self {
            self.as_mut().rev_sort();
            self
        }
    }
    impl<T: Ord, V: AsMut<[T]>> Sorted<T> for V {}

    pub use bit::*;
    pub mod bit {
        use std::ops::{BitAnd, Shr, ShrAssign};

        pub trait Bit: Sized + BitAnd<Output = Self> + Eq + Copy + Shr<u8, Output = Self> + ShrAssign<u8> {
            fn zero() -> Self;
            fn one() -> Self;
            fn bit<P>(self, pos: P) -> bool where Self: Shr<P, Output = Self> {
                (self >> pos) & Self::one() == Self::one()
            }
            fn bits(self) -> Bits<Self> { Bits::new(self) }
        }

        #[derive(Debug, Clone)]
        pub struct Bits<T: Bit> { n: T }
        impl<T: Bit> Bits<T> { fn new(n: T) -> Self { Self {n} } }
        impl<T: Bit> Iterator for Bits<T> {
            type Item = bool;
            fn next(&mut self) -> Option<Self::Item> {
                if self.n == T::zero() { return None }
                let ret = self.n & T::one() == T::one();
                self.n >>= 1;
                Some(ret)
            }
        }

        macro_rules! impl_trait {
            ($($type:ty)*) => { $(impl Bit for $type {
                #[inline(always)] fn zero() -> Self { 0 }
                #[inline(always)] fn one() -> Self { 1 } 
            })*};
        }
        impl_trait!(u8 u16 u32 u64 u128 usize);
    }

    pub trait Print: Display {
        fn print(&self) { print!("{self}"); }
        fn println(&self) { println!("{self}"); }
        fn eprint(&self) { eprint!("{self}"); }
        fn eprintln(&self) { eprintln!("{self}"); }
    }
    impl<T: Display> Print for T {}

    pub trait DebugPrint: Debug {
        fn dprint(&self) { eprint!("{self:?}"); }
        fn dprintln(&self) { eprintln!("{self:?}"); }
    }
    impl<T: Debug> DebugPrint for T {}

    pub fn primes(max: usize) -> Vec<usize> {
        let mut is_prime = vec![true; max];
        is_prime[0..=1].fill(false);
        for i in 2.. {
            if i*i >= max { break; }
            if is_prime[i] {
                let mut temp = i*2;
                while temp < max { is_prime[temp] = false; temp += i; }
            }
        }
        is_prime.into_iter().enumerate().filter(|&(_, is_prime)| is_prime).map(|(n, _)| n).collect()
    }

    pub trait CharsToString {
        fn to_string(&self) -> String;
    }
    impl CharsToString for [char] {
        fn to_string(&self) -> String { self.iter().collect() }
    }

    pub use slice_ext::*;
    pub mod slice_ext {
        use std::{fmt::Display, iter::FusedIterator};
        use itertools::Itertools;

        pub trait SliceExt<T> {
            fn rev_sort(&mut self) where T: Ord;
            fn get_elem<Idx: TryInto<usize>>(&self, index: Idx) -> Option<&T>;
            fn space_separate_print(&self) where T: Display;
            fn line_separate_print(&self) where T: Display;
            fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>;
        }
        impl<T> SliceExt<T> for [T] {
            fn rev_sort(&mut self) where T: Ord { self.sort_by(|l, r| r.cmp(l)); }
            fn get_elem<Idx: TryInto<usize>>(&self, index: Idx) -> Option<&T> {
                let index: usize = index.try_into().ok()?;
                self.get(index)
            }
            fn space_separate_print(&self) where T: Display {
                println!("{}", self.iter().join(" "));
            }
            fn line_separate_print(&self) where T: Display {
                println!("{}", self.iter().join("\n"));
            }
            #[inline]
            fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
                ArrayWindows::new(self)
            }
        }

        struct IsNonZero<const N: usize>;
        impl<const N: usize> IsNonZero<N> { const OK: () = assert!(N > 0, "size must be non-zero"); }

        #[derive(Debug, Clone)]
        pub struct ArrayWindows<'a, T, const N: usize> {
            slice: &'a [T],
        }
        impl<'a, T, const N: usize> ArrayWindows<'a, T, N> {
            fn new(slice: &'a [T]) -> Self {
                let _ = IsNonZero::<N>::OK;
                Self { slice }
            }
        }
        impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
            type Item = &'a [T; N];
            fn next(&mut self) -> Option<Self::Item> {
                if self.slice.len() < N {
                    None
                } else {
                    let ret = self.slice[..N].try_into().unwrap();
                    self.slice = &self.slice[1..];
                    Some(ret)
                }
            }
            fn count(self) -> usize where Self: Sized { self.len() }
            fn size_hint(&self) -> (usize, Option<usize>) {
                let len = self.len();
                (len, Some(len))
            }
            fn nth(&mut self, n: usize) -> Option<Self::Item> {
                if self.len() < n + 1 {
                    self.slice = &[];
                    None
                } else {
                    self.slice = &self.slice[n..];
                    self.next()
                }
            }
        }
        impl<'a, T, const N: usize> ExactSizeIterator for ArrayWindows<'a, T, N> {
            fn len(&self) -> usize { self.slice.len().saturating_sub(N - 1) }
        }
        impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
            fn next_back(&mut self) -> Option<Self::Item> {
                if self.slice.len() < N {
                    None
                } else {
                    let ret = self.slice[self.slice.len() - N..].try_into().unwrap();
                    self.slice = &self.slice[..self.slice.len() - 1];
                    Some(ret)
                }
            }
            fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
                if self.len() < n + 1 {
                    self.slice = &[];
                    None
                } else {
                    self.slice = &self.slice[..self.slice.len() - n];
                    self.next_back()
                }
            }
        }
        impl<'a, T, const N: usize> FusedIterator for ArrayWindows<'a, T, N> {}
    }
}
0