提出 #28386443


ソースコード 拡げる

use proconio::{fastout, input};

use nekolib::{ds::WaveletMatrix, traits::Quantile};

#[fastout]
fn main() {
    input! {
        n: usize,
        k: usize,
        p: [u128; n],
    }

    let wm: WaveletMatrix = p.into();
    for i in k..=n {
        println!("{}", wm.quantile(0..i, i - k).unwrap());
    }
}

/// This module is bundled automatically.
/// See <https://rsk0315.github.io/library-rs/nekolib/> for documentation.
pub mod nekolib {
    pub mod ds {
        pub mod rs_dict {
            use super::super::traits::count;
            use super::super::traits::find_nth;
            use super::super::utils::buf_range;
            use buf_range::bounds_within;
            use count::Count;
            use find_nth::FindNth;
            use std::fmt::Debug;
            use std::ops::{Range, RangeBounds};
            const WORD_SIZE: usize = 64;
            const WORD_SIZE_2: usize = WORD_SIZE * WORD_SIZE;
            #[derive(Clone, Debug)]
            pub struct RsDict {
                len: usize,
                buf: Vec<u64>,
                rank: Vec<usize>,
                sel0: Vec<SelectPreprocess>,
                sel1: Vec<SelectPreprocess>,
            }
            #[derive(Clone, Debug)]
            enum SelectPreprocess {
                Sparse(Vec<usize>),
                Dense(Range<usize>),
            }
            use SelectPreprocess::{Dense, Sparse};
            impl From<Vec<bool>> for RsDict {
                fn from(buf: Vec<bool>) -> Self {
                    let len = buf.len();
                    let buf = Self::compress_vec_bool(buf);
                    let rank = Self::preprocess_rank(&buf);
                    let sel0 = Self::preprocess_select(&buf, len, 0);
                    let sel1 = Self::preprocess_select(&buf, len, 1);
                    Self { len, buf, rank, sel0, sel1 }
                }
            }
            impl RsDict {
                fn compress_vec_bool(buf: Vec<bool>) -> Vec<u64> {
                    if buf.is_empty() {
                        return vec![];
                    }
                    let n = buf.len();
                    let nc = 1 + (n - 1) / WORD_SIZE;
                    let mut res = vec![0; nc + 1];
                    for i in 0..n {
                        if buf[i] {
                            res[i / WORD_SIZE] |= 1_u64 << (i % WORD_SIZE);
                        }
                    }
                    res
                }
                fn preprocess_rank(buf: &[u64]) -> Vec<usize> {
                    let n = buf.len();
                    let mut res = vec![0; n];
                    for i in 1..n {
                        res[i] = res[i - 1] + buf[i - 1].count_ones() as usize;
                    }
                    res
                }
                fn preprocess_select(
                    buf: &[u64],
                    n: usize,
                    x: u64,
                ) -> Vec<SelectPreprocess> {
                    let mut sel = vec![];
                    let mut tmp = vec![];
                    let mut last = 0;
                    for i in 0..n {
                        if buf[i / WORD_SIZE] >> (i % WORD_SIZE) & 1 != x {
                            continue;
                        }
                        if tmp.len() == WORD_SIZE {
                            let len = i - last;
                            if len < WORD_SIZE_2 {
                                sel.push(Dense(last..i));
                            } else {
                                sel.push(Sparse(tmp));
                            }
                            tmp = vec![];
                            last = i;
                        }
                        tmp.push(i);
                    }
                    if !tmp.is_empty() {
                        sel.push(Sparse(tmp));
                    }
                    sel
                }
                pub fn rank(&self, end: usize, x: u64) -> usize {
                    let il = end / WORD_SIZE;
                    let is = end % WORD_SIZE;
                    let rank1 = self.rank[il]
                        + (self.buf[il] & !(!0_u64 << is)).count_ones()
                            as usize;
                    let rank = if x == 0 { end - rank1 } else { rank1 };
                    rank
                }
                pub fn select(&self, x: u64, k: usize) -> Option<usize> {
                    if self.rank(self.len, x) < k {
                        None
                    } else if k == 0 {
                        Some(0)
                    } else {
                        Some(self.find_nth_internal(x, k - 1) + 1)
                    }
                }
            }
            impl Count<u64> for RsDict {
                fn count(&self, r: impl RangeBounds<usize>, x: u64) -> usize {
                    let Range { start, end } = bounds_within(r, self.len);
                    if start > 0 {
                        self.rank(end, x) - self.rank(start, x)
                    } else {
                        self.rank(end, x)
                    }
                }
            }
            impl FindNth<u64> for RsDict {
                fn find_nth(
                    &self,
                    r: impl RangeBounds<usize>,
                    x: u64,
                    n: usize,
                ) -> Option<usize> {
                    let Range { start, end } = bounds_within(r, self.len);
                    if self.count(start..end, x) <= n {
                        None
                    } else {
                        let offset = self.rank(start, x);
                        Some(self.find_nth_internal(x, offset + n))
                    }
                }
            }
            impl RsDict {
                fn find_nth_internal(&self, x: u64, n: usize) -> usize {
                    if self.rank(self.len, x) < n {
                        panic!("the number of {}s is less than {}", x, n);
                    }
                    let sel = if x == 0 { &self.sel0 } else { &self.sel1 };
                    let il = n / WORD_SIZE;
                    let is = n % WORD_SIZE;
                    eprintln!("{:?}", sel[il]);
                    match &sel[il] {
                        Sparse(dir) => dir[is],
                        Dense(range) => {
                            let mut lo = range.start / WORD_SIZE;
                            let mut hi = 1 + (range.end - 1) / WORD_SIZE;
                            while hi - lo > 1 {
                                let mid = lo + (hi - lo) / 2;
                                let rank = self.rank_rough(mid, x);
                                *(if rank <= n { &mut lo } else { &mut hi }) =
                                    mid;
                            }
                            let rank_frac = n - self.rank_rough(lo, x);
                            lo * WORD_SIZE
                                + Self::find_nth_small(
                                    self.buf[lo],
                                    x,
                                    rank_frac,
                                )
                        }
                    }
                }
                fn rank_rough(&self, n: usize, x: u64) -> usize {
                    let rank1 = self.rank[n];
                    let rank =
                        if x == 0 { n * WORD_SIZE - rank1 } else { rank1 };
                    rank
                }
                fn find_nth_small(word: u64, x: u64, n: usize) -> usize {
                    let mut word = if x == 0 { !word } else { word };
                    let mut n = n as u32;
                    let mut res = 0;
                    for &mid in &[32, 16, 8, 4, 2, 1] {
                        let count = (word & !(!0 << mid)).count_ones();
                        if count <= n {
                            n -= count;
                            word >>= mid;
                            res += mid;
                        }
                    }
                    res
                }
            }
        }
        pub use rs_dict::RsDict;
        pub mod wavelet_matrix {
            use super::super::traits::count;
            use super::super::traits::find_nth;
            use super::super::traits::quantile;
            use super::super::utils::buf_range;
            use super::rs_dict;
            use buf_range::bounds_within;
            use count::{Count, Count3way, Count3wayResult};
            use find_nth::FindNth;
            use quantile::Quantile;
            use rs_dict::RsDict;
            use std::ops::{
                Bound::{Excluded, Included, Unbounded},
                Range, RangeBounds,
            };
            pub struct WaveletMatrix {
                len: usize,
                bitlen: usize,
                buf: Vec<RsDict>,
                zeros: Vec<usize>,
            }
            impl From<Vec<u128>> for WaveletMatrix {
                fn from(orig: Vec<u128>) -> Self {
                    if orig.is_empty() {
                        return Self {
                            len: 0,
                            bitlen: 0,
                            buf: vec![],
                            zeros: vec![],
                        };
                    }
                    let len = orig.len();
                    let mut whole = orig.clone();
                    let &max = orig.iter().max().unwrap();
                    let bitlen = if max >= 1 << 127 {
                        128
                    } else {
                        (max + 1).next_power_of_two().trailing_zeros() as usize
                    };
                    let mut zeros = vec![0; bitlen];
                    let mut buf = vec![];
                    for i in (0..bitlen).rev() {
                        let mut zero = vec![];
                        let mut one = vec![];
                        let mut vb = vec![false; len];
                        for j in 0..len {
                            (if whole[j] >> i & 1 == 0 {
                                &mut zero
                            } else {
                                &mut one
                            })
                            .push(whole[j]);
                            vb[j] = whole[j] >> i & 1 != 0;
                        }
                        zeros[i] = zero.len();
                        buf.push(vb.into());
                        whole = zero;
                        whole.append(&mut one);
                    }
                    buf.reverse();
                    Self { len, bitlen, buf, zeros }
                }
            }
            impl<R: RangeBounds<u128>> Count<R> for WaveletMatrix {
                fn count(
                    &self,
                    range: impl RangeBounds<usize>,
                    value: R,
                ) -> usize {
                    self.count_3way(range, value).eq()
                }
            }
            impl<R: RangeBounds<u128>> Count3way<R> for WaveletMatrix {
                fn count_3way(
                    &self,
                    range: impl RangeBounds<usize>,
                    value: R,
                ) -> Count3wayResult {
                    let Range { start, end } = bounds_within(range, self.len);
                    let len = end - start;
                    let lt = match value.start_bound() {
                        Included(&x) => {
                            self.count_3way_internal(start..end, x).0
                        }
                        Excluded(&std::u128::MAX) => len,
                        Excluded(&x) => {
                            self.count_3way_internal(start..end, x + 1).0
                        }
                        Unbounded => 0,
                    };
                    let gt = match value.end_bound() {
                        Included(&x) => {
                            self.count_3way_internal(start..end, x).1
                        }
                        Excluded(&0) => len,
                        Excluded(&x) => {
                            self.count_3way_internal(start..end, x - 1).1
                        }
                        Unbounded => 0,
                    };
                    let eq = len - (lt + gt);
                    Count3wayResult::new(lt, eq, gt)
                }
            }
            impl WaveletMatrix {
                fn count_3way_internal(
                    &self,
                    Range { mut start, mut end }: Range<usize>,
                    value: u128,
                ) -> (usize, usize) {
                    if start == end {
                        return (0, 0);
                    }
                    let mut lt = 0;
                    let mut gt = 0;
                    for i in (0..self.bitlen).rev() {
                        let tmp = end - start;
                        if value >> i & 1 == 0 {
                            start = self.buf[i].rank(start, 0);
                            end = self.buf[i].rank(end, 0);
                        } else {
                            start = self.zeros[i] + self.buf[i].rank(start, 1);
                            end = self.zeros[i] + self.buf[i].rank(end, 1);
                        }
                        *(if value >> i & 1 == 0 {
                            &mut gt
                        } else {
                            &mut lt
                        }) += tmp - (end - start);
                    }
                    (lt, gt)
                }
            }
            impl Quantile for WaveletMatrix {
                type Output = u128;
                fn quantile(
                    &self,
                    range: impl RangeBounds<usize>,
                    mut n: usize,
                ) -> Option<u128> {
                    let Range { mut start, mut end } =
                        bounds_within(range, self.len);
                    if end - start <= n {
                        return None;
                    }
                    let mut res = 0;
                    for i in (0..self.bitlen).rev() {
                        let z = self.buf[i].count(start..end, 0);
                        if n < z {
                            start = self.buf[i].rank(start, 0);
                            end = self.buf[i].rank(end, 0);
                        } else {
                            res |= 1_u128 << i;
                            start = self.zeros[i] + self.buf[i].rank(start, 1);
                            end = self.zeros[i] + self.buf[i].rank(end, 1);
                            n -= z;
                        }
                    }
                    Some(res)
                }
            }
            impl WaveletMatrix {
                pub fn xored_quantile(
                    &self,
                    range: impl RangeBounds<usize>,
                    mut n: usize,
                    x: u128,
                ) -> Option<u128> {
                    let Range { mut start, mut end } =
                        bounds_within(range, self.len);
                    if end - start <= n {
                        return None;
                    }
                    let mut res = 0;
                    for i in (0..self.bitlen).rev() {
                        let z = self.buf[i].count(start..end, 0);
                        if x >> i & 1 == 0 {
                            if n < z {
                                start = self.buf[i].rank(start, 0);
                                end = self.buf[i].rank(end, 0);
                            } else {
                                res |= 1_u128 << i;
                                start =
                                    self.zeros[i] + self.buf[i].rank(start, 1);
                                end = self.zeros[i] + self.buf[i].rank(end, 1);
                                n -= z;
                            }
                        } else {
                            let z = (end - start) - z;
                            if n < z {
                                start =
                                    self.zeros[i] + self.buf[i].rank(start, 1);
                                end = self.zeros[i] + self.buf[i].rank(end, 1);
                            } else {
                                res |= 1_u128 << i;
                                start = self.buf[i].rank(start, 0);
                                end = self.buf[i].rank(end, 0);
                                n -= z;
                            }
                        }
                    }
                    Some(res)
                }
            }
            impl FindNth<u128> for WaveletMatrix {
                fn find_nth(
                    &self,
                    range: impl RangeBounds<usize>,
                    value: u128,
                    n: usize,
                ) -> Option<usize> {
                    let start = bounds_within(range, self.len).start;
                    let (lt, gt) = self.count_3way_internal(0..start, value);
                    let offset = start - (lt + gt);
                    Some(self.select(value, n + offset + 1)? - 1)
                }
            }
            impl WaveletMatrix {
                pub fn rank(&self, end: usize, value: u128) -> usize {
                    self.count(0..end, value..=value)
                }
                pub fn select(
                    &self,
                    value: u128,
                    mut n: usize,
                ) -> Option<usize> {
                    if n == 0 {
                        return Some(0);
                    }
                    let (lt, gt) = self.count_3way_internal(0..self.len, value);
                    let count = self.len - (lt + gt);
                    if count < n {
                        return None;
                    }
                    let si = self.start_pos(value);
                    let value0 = (value & 1) as u64;
                    n += self.buf[0].rank(si, value0);
                    n = self.buf[0].select(value0, n).unwrap();
                    for i in 1..self.bitlen {
                        if value >> i & 1 == 0 {
                            n = self.buf[i].select(0, n).unwrap();
                        } else {
                            n -= self.zeros[i];
                            n = self.buf[i].select(1, n).unwrap();
                        }
                    }
                    Some(n)
                }
                fn start_pos(&self, value: u128) -> usize {
                    let mut start = 0;
                    let mut end = 0;
                    for i in (1..self.bitlen).rev() {
                        if value >> i & 1 == 0 {
                            start = self.buf[i].rank(start, 0);
                            end = self.buf[i].rank(end, 0);
                        } else {
                            start = self.zeros[i] + self.buf[i].rank(start, 1);
                            end = self.zeros[i] + self.buf[i].rank(end, 1);
                        }
                    }
                    start
                }
            }
        }
        pub use wavelet_matrix::WaveletMatrix;
    }
    pub mod traits {
        pub mod count {
            use std::fmt::Debug;
            use std::ops::RangeBounds;
            pub trait Count<I> {
                fn count(
                    &self,
                    range: impl RangeBounds<usize>,
                    value: I,
                ) -> usize;
            }
            pub trait Count3way<I> {
                fn count_3way(
                    &self,
                    range: impl RangeBounds<usize>,
                    value: I,
                ) -> Count3wayResult;
            }
            #[derive(Clone, Copy, Debug, Eq, PartialEq)]
            pub struct Count3wayResult {
                lt: usize,
                eq: usize,
                gt: usize,
            }
            impl Count3wayResult {
                pub fn new(lt: usize, eq: usize, gt: usize) -> Self {
                    Self { lt, eq, gt }
                }
                pub fn lt(&self) -> usize { self.lt }
                pub fn eq(&self) -> usize { self.eq }
                pub fn gt(&self) -> usize { self.gt }
                pub fn le(&self) -> usize { self.lt + self.eq }
                pub fn ge(&self) -> usize { self.gt + self.eq }
                pub fn ne(&self) -> usize { self.lt + self.gt }
            }
        }
        pub use count::{Count, Count3way};
        pub mod find_nth {
            use std::ops::RangeBounds;
            pub trait FindNth<I> {
                fn find_nth(
                    &self,
                    range: impl RangeBounds<usize>,
                    value: I,
                    n: usize,
                ) -> Option<usize>;
            }
        }
        pub use find_nth::FindNth;
        pub mod quantile {
            use std::ops::RangeBounds;
            pub trait Quantile {
                type Output;
                fn quantile(
                    &self,
                    range: impl RangeBounds<usize>,
                    n: usize,
                ) -> Option<Self::Output>;
            }
        }
        pub use quantile::Quantile;
    }
    pub mod utils {
        pub mod buf_range {
            use std::ops::Bound::{Excluded, Included, Unbounded};
            use std::ops::{Range, RangeBounds};
            pub fn bounds_within<R: RangeBounds<usize>>(
                r: R,
                len: usize,
            ) -> Range<usize> {
                let e_ex = match r.end_bound() {
                    Included(&e) => e + 1,
                    Excluded(&e) => e,
                    Unbounded => len,
                }
                .min(len);
                let s_in = match r.start_bound() {
                    Included(&s) => s,
                    Excluded(&s) => s + 1,
                    Unbounded => 0,
                }
                .min(e_ex);
                s_in..e_ex
            }
        }
        pub use buf_range::bounds_within;
    }
}

提出情報

提出日時
問題 D - Prefix K-th Max
ユーザ rsk0315
言語 Rust (1.42.0)
得点 400
コード長 22687 Byte
結果 AC
実行時間 512 ms
メモリ 43232 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 400 / 400
結果
AC × 2
AC × 28
セット名 テストケース
Sample example0.txt, example1.txt
All 000.txt, 001.txt, 002.txt, 003.txt, 004.txt, 005.txt, 006.txt, 007.txt, 008.txt, 009.txt, 010.txt, 011.txt, 012.txt, 013.txt, 014.txt, 015.txt, 016.txt, 017.txt, 018.txt, 019.txt, 020.txt, 021.txt, 022.txt, 023.txt, 024.txt, 025.txt, example0.txt, example1.txt
ケース名 結果 実行時間 メモリ
000.txt AC 7 ms 2056 KiB
001.txt AC 512 ms 43108 KiB
002.txt AC 322 ms 43232 KiB
003.txt AC 420 ms 42952 KiB
004.txt AC 443 ms 42864 KiB
005.txt AC 404 ms 41048 KiB
006.txt AC 246 ms 21412 KiB
007.txt AC 470 ms 42600 KiB
008.txt AC 170 ms 20156 KiB
009.txt AC 191 ms 21040 KiB
010.txt AC 372 ms 42884 KiB
011.txt AC 362 ms 41636 KiB
012.txt AC 187 ms 42876 KiB
013.txt AC 183 ms 41736 KiB
014.txt AC 281 ms 42740 KiB
015.txt AC 273 ms 41672 KiB
016.txt AC 280 ms 42964 KiB
017.txt AC 272 ms 41608 KiB
018.txt AC 355 ms 40524 KiB
019.txt AC 367 ms 42628 KiB
020.txt AC 178 ms 40540 KiB
021.txt AC 187 ms 42720 KiB
022.txt AC 285 ms 40536 KiB
023.txt AC 278 ms 42644 KiB
024.txt AC 273 ms 40440 KiB
025.txt AC 276 ms 42656 KiB
example0.txt AC 4 ms 2012 KiB
example1.txt AC 1 ms 2100 KiB