提出 #62785883
ソースコード 拡げる
use proconio::{input, marker::Usize1};
use riff::SliceBinarySearch;
fn main() {
input! {
n: usize,
q: usize,
a: [u32; n],
raw_queries: [(Usize1, u32); q],
}
let mut queries = vec![vec![]; n];
for (i, &(r, _)) in raw_queries.iter().enumerate() {
queries[r].push(i);
}
let mut dp = vec![];
let mut ans = vec![usize::MAX; q];
for (i, &x) in a.iter().enumerate() {
let lb = dp.lower_bound(&x);
if dp.len() == lb {
dp.push(x);
} else {
dp[lb] = x;
}
for &j in &queries[i] {
let (_, x) = raw_queries[j];
ans[j] = dp.upper_bound(&x);
}
}
for &ans in &ans {
println!("{ans}");
}
}
// riff {{{
// https://ngtkana.github.io/ac-adapter-rs/riff/index.html
#[allow(dead_code)]
mod riff {
mod bitmask_iterators {
use super::numeric_traits::Unsigned;
pub fn bitmask_combinations<T: Unsigned>(n: u32, k: u32) -> BitmaskCombinations<T> {
assert!(k < T::bit_length() && k < T::bit_length());
BitmaskCombinations {
n,
bs: (T::ONE << k) - T::ONE,
}
}
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
pub struct BitmaskCombinations<T> {
n: u32,
bs: T,
}
impl<T: Unsigned> Iterator for BitmaskCombinations<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if (T::ONE << self.n) <= self.bs {
return None;
}
let res = Some(self.bs);
self.bs = if self.bs == T::ZERO {
T::ONE << self.n
} else {
let x = self.bs & self.bs.wrapping_neg();
let y = self.bs + x;
(((self.bs & !y) / x) >> 1) | y
};
res
}
}
pub fn bitmask_subsets<T: Unsigned>(bs: T) -> BitmaskSubsets<T> {
BitmaskSubsets {
bs,
full: bs,
finished: false,
}
}
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
pub struct BitmaskSubsets<T> {
bs: T,
full: T,
finished: bool,
}
impl<T: Unsigned> Iterator for BitmaskSubsets<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
let res = Some(self.bs ^ self.full);
if self.bs == T::ZERO {
self.finished = true;
} else {
self.bs -= T::ONE;
self.bs &= self.full;
}
res
}
}
}
mod bitmask_operations {
use crate::riff::Unsigned;
pub fn i2powm1<T: Unsigned>(n: u32) -> T {
if n == T::bit_length() {
T::MAX
} else {
(T::ONE << n) - T::ONE
}
}
}
mod change_min_max {
pub trait ChangeMinMax: PartialOrd + Sized {
fn change_min(&mut self, rhs: Self) {
if *self > rhs {
*self = rhs
}
}
fn change_max(&mut self, rhs: Self) {
if *self < rhs {
*self = rhs
}
}
}
impl<T: PartialOrd + Sized> ChangeMinMax for T {}
}
mod numeric_traits {
use std::fmt::Debug;
use std::mem::size_of;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::BitAnd;
use std::ops::BitAndAssign;
use std::ops::BitOr;
use std::ops::BitOrAssign;
use std::ops::BitXor;
use std::ops::BitXorAssign;
use std::ops::Div;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Not;
use std::ops::Shl;
use std::ops::ShlAssign;
use std::ops::Shr;
use std::ops::ShrAssign;
use std::ops::Sub;
use std::ops::SubAssign;
pub trait Unsigned:
Sized
+ PartialEq
+ PartialOrd
+ Debug
+ Clone
+ Copy
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Mul<Output = Self>
+ MulAssign
+ Div<Output = Self>
+ DivAssign
+ BitAnd<Output = Self>
+ BitAndAssign
+ BitOr<Output = Self>
+ BitOrAssign
+ BitXor<Output = Self>
+ BitXorAssign
+ Shl<u32, Output = Self>
+ ShlAssign<u32>
+ Shr<u32, Output = Self>
+ ShrAssign<u32>
+ Not<Output = Self>
{
const BITS: u32;
const MAX: Self;
const ZERO: Self;
const ONE: Self;
fn wrapping_neg(self) -> Self;
fn bit_length() -> u32 {
size_of::<Self>() as u32 * 8
}
}
macro_rules! impl_unsigned {
($($T:ty),* $(,)?) => {$(
impl Unsigned for $T {
const BITS: u32 = <$T>::BITS;
const MAX: Self = <$T>::MAX;
const ZERO: Self = 0;
const ONE: Self = 1;
fn wrapping_neg(self) -> Self { self.wrapping_neg() }
}
)*}
}
impl_unsigned! { usize, u8, u16, u32, u64, u128 }
}
mod pop_if {
use std::collections::BinaryHeap;
pub trait PopIf {
type Value;
fn pop_if<F>(&mut self, f: F) -> Option<Self::Value>
where
F: FnOnce(&mut Self::Value) -> bool;
}
impl<T> PopIf for Vec<T> {
type Value = T;
fn pop_if<F>(&mut self, f: F) -> Option<Self::Value>
where
F: FnOnce(&mut Self::Value) -> bool,
{
if f(self.last_mut()?) {
self.pop()
} else {
None
}
}
}
impl<T: Ord> PopIf for BinaryHeap<T> {
type Value = T;
fn pop_if<F>(&mut self, f: F) -> Option<Self::Value>
where
F: FnOnce(&mut Self::Value) -> bool,
{
if f(&mut *self.peek_mut()?) {
self.pop()
} else {
None
}
}
}
}
mod slice_accum {
use std::ops::AddAssign;
use std::ops::SubAssign;
pub trait SliceAccum<T> {
fn for_each_forward<F>(&mut self, f: F)
where
F: FnMut(&mut T, &mut T);
fn for_each_backward<F>(&mut self, f: F)
where
F: FnMut(&mut T, &mut T);
fn prefix_sum(&mut self)
where
for<'a> T: AddAssign<&'a T>,
{
self.for_each_forward(|x, y| *x += y);
}
fn prefix_sum_inv(&mut self)
where
for<'a> T: SubAssign<&'a T>,
{
self.for_each_backward(|x, y| *y -= x);
}
fn suffix_sum(&mut self)
where
for<'a> T: AddAssign<&'a T>,
{
self.for_each_backward(|x, y| *x += y);
}
fn suffix_sum_inv(&mut self)
where
for<'a> T: SubAssign<&'a T>,
{
self.for_each_forward(|x, y| *y -= x);
}
}
impl<T> SliceAccum<T> for [T] {
fn for_each_forward<F>(&mut self, mut f: F)
where
F: FnMut(&mut T, &mut T),
{
for i in 1..self.len() {
let (left, right) = self.split_at_mut(i);
f(&mut right[0], &mut left[i - 1]);
}
}
fn for_each_backward<F>(&mut self, mut f: F)
where
F: FnMut(&mut T, &mut T),
{
for i in (1..self.len()).rev() {
let (left, right) = self.split_at_mut(i);
f(&mut left[i - 1], &mut right[0]);
}
}
}
}
mod slice_binary_search {
use std::cmp::Ordering;
use std::cmp::Ordering::Equal;
use std::cmp::Ordering::Greater;
use std::cmp::Ordering::Less;
pub trait SliceBinarySearch<T> {
fn partition_point<F: FnMut(&T) -> bool>(&self, pred: F) -> usize;
fn partition_point_value<F: FnMut(&T) -> bool>(&self, pred: F) -> Option<&T>;
fn lower_bound_by<F: FnMut(&T) -> Ordering>(&self, mut f: F) -> usize {
self.partition_point(|x| f(x) < Equal)
}
fn upper_bound_by<F: FnMut(&T) -> Ordering>(&self, mut f: F) -> usize {
self.partition_point(|x| f(x) <= Equal)
}
fn lower_bound_by_key<B: Ord, F: FnMut(&T) -> B>(&self, b: &B, mut f: F) -> usize {
self.lower_bound_by(|x| f(x).cmp(b))
}
fn upper_bound_by_key<B: Ord, F: FnMut(&T) -> B>(&self, b: &B, mut f: F) -> usize {
self.upper_bound_by(|x| f(x).cmp(b))
}
fn lower_bound(&self, x: &T) -> usize
where
T: Ord,
{
self.lower_bound_by(|p| p.cmp(x))
}
fn upper_bound(&self, x: &T) -> usize
where
T: Ord,
{
self.upper_bound_by(|p| p.cmp(x))
}
fn lower_bound_value_by<F: FnMut(&T) -> Ordering>(&self, mut f: F) -> Option<&T> {
self.partition_point_value(|x| f(x) < Equal)
}
fn upper_bound_value_by<F: FnMut(&T) -> Ordering>(&self, mut f: F) -> Option<&T> {
self.partition_point_value(|x| f(x) <= Equal)
}
fn lower_bound_value_by_key<B: Ord, F: FnMut(&T) -> B>(
&self,
b: &B,
mut f: F,
) -> Option<&T> {
self.lower_bound_value_by(|x| f(x).cmp(b))
}
fn upper_bound_value_by_key<B: Ord, F: FnMut(&T) -> B>(
&self,
b: &B,
mut f: F,
) -> Option<&T> {
self.upper_bound_value_by(|x| f(x).cmp(b))
}
fn lower_bound_value(&self, x: &T) -> Option<&T>
where
T: Ord,
{
self.lower_bound_value_by(|p| p.cmp(x))
}
fn upper_bound_value(&self, x: &T) -> Option<&T>
where
T: Ord,
{
self.upper_bound_value_by(|p| p.cmp(x))
}
}
impl<T> SliceBinarySearch<T> for [T] {
fn partition_point<F: FnMut(&T) -> bool>(&self, mut pred: F) -> usize {
self.binary_search_by(|x| if pred(x) { Less } else { Greater })
.unwrap_err()
}
fn partition_point_value<F: FnMut(&T) -> bool>(&self, pred: F) -> Option<&T> {
self.get(self.partition_point(pred))
}
}
}
mod slice_chunks {
pub trait SliceChunks {
type Item;
fn chunk_by<F>(&self, f: F) -> SliceChunkBy<'_, Self::Item, F>
where
F: FnMut(&Self::Item, &Self::Item) -> bool;
}
impl<T> SliceChunks for [T] {
type Item = T;
fn chunk_by<F>(&self, f: F) -> SliceChunkBy<'_, Self::Item, F>
where
F: FnMut(&Self::Item, &Self::Item) -> bool,
{
SliceChunkBy { a: self, f }
}
}
pub struct SliceChunkBy<'a, T, F> {
a: &'a [T],
f: F,
}
impl<'a, T, F> Iterator for SliceChunkBy<'a, T, F>
where
F: FnMut(&T, &T) -> bool,
{
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
let Self { a, f } = self;
if a.is_empty() {
return None;
}
let mut end = 1;
while end < a.len() && f(&a[end - 1], &a[end]) {
end += 1;
}
let (prefix, rest) = a.split_at(end);
self.a = rest;
Some(prefix)
}
}
}
pub use bitmask_iterators::bitmask_combinations;
pub use bitmask_iterators::bitmask_subsets;
pub use bitmask_operations::i2powm1;
pub use change_min_max::ChangeMinMax;
pub use numeric_traits::Unsigned;
pub use pop_if::PopIf;
pub use slice_accum::SliceAccum;
pub use slice_binary_search::SliceBinarySearch;
pub use slice_chunks::SliceChunks;
}
// }}}
提出情報
| 提出日時 |
|
| 問題 |
F - Prefix LIS Query |
| ユーザ |
ngtkana |
| 言語 |
Rust (rustc 1.70.0) |
| 得点 |
500 |
| コード長 |
13690 Byte |
| 結果 |
AC |
| 実行時間 |
243 ms |
| メモリ |
26560 KiB |
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
500 / 500 |
| 結果 |
|
|
| セット名 |
テストケース |
| Sample |
00_sample_00.txt, 00_sample_01.txt |
| All |
00_sample_00.txt, 00_sample_01.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 01_random_10.txt, 01_random_11.txt, 01_random_12.txt, 01_random_13.txt, 01_random_14.txt, 02_random2_00.txt, 02_random2_01.txt, 02_random2_02.txt, 02_random2_03.txt, 02_random2_04.txt, 03_random3_00.txt, 03_random3_01.txt, 03_random3_02.txt, 03_random3_03.txt, 03_random3_04.txt, 03_random3_05.txt, 03_random3_06.txt, 03_random3_07.txt, 03_random3_08.txt, 03_random3_09.txt, 04_handmade_00.txt, 04_handmade_01.txt, 04_handmade_02.txt, 04_handmade_03.txt, 04_handmade_04.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 00_sample_00.txt |
AC |
0 ms |
1928 KiB |
| 00_sample_01.txt |
AC |
1 ms |
1996 KiB |
| 01_random_00.txt |
AC |
0 ms |
2144 KiB |
| 01_random_01.txt |
AC |
181 ms |
10328 KiB |
| 01_random_02.txt |
AC |
18 ms |
9264 KiB |
| 01_random_03.txt |
AC |
30 ms |
8056 KiB |
| 01_random_04.txt |
AC |
109 ms |
11088 KiB |
| 01_random_05.txt |
AC |
147 ms |
11696 KiB |
| 01_random_06.txt |
AC |
233 ms |
22872 KiB |
| 01_random_07.txt |
AC |
232 ms |
22968 KiB |
| 01_random_08.txt |
AC |
232 ms |
23016 KiB |
| 01_random_09.txt |
AC |
235 ms |
23076 KiB |
| 01_random_10.txt |
AC |
231 ms |
22980 KiB |
| 01_random_11.txt |
AC |
231 ms |
22912 KiB |
| 01_random_12.txt |
AC |
232 ms |
22956 KiB |
| 01_random_13.txt |
AC |
232 ms |
23028 KiB |
| 01_random_14.txt |
AC |
231 ms |
22904 KiB |
| 02_random2_00.txt |
AC |
210 ms |
18764 KiB |
| 02_random2_01.txt |
AC |
211 ms |
18800 KiB |
| 02_random2_02.txt |
AC |
212 ms |
19212 KiB |
| 02_random2_03.txt |
AC |
213 ms |
19012 KiB |
| 02_random2_04.txt |
AC |
243 ms |
26372 KiB |
| 03_random3_00.txt |
AC |
234 ms |
24116 KiB |
| 03_random3_01.txt |
AC |
211 ms |
23088 KiB |
| 03_random3_02.txt |
AC |
235 ms |
24020 KiB |
| 03_random3_03.txt |
AC |
210 ms |
23044 KiB |
| 03_random3_04.txt |
AC |
231 ms |
24108 KiB |
| 03_random3_05.txt |
AC |
216 ms |
23004 KiB |
| 03_random3_06.txt |
AC |
233 ms |
23644 KiB |
| 03_random3_07.txt |
AC |
216 ms |
23012 KiB |
| 03_random3_08.txt |
AC |
239 ms |
23808 KiB |
| 03_random3_09.txt |
AC |
228 ms |
22912 KiB |
| 04_handmade_00.txt |
AC |
216 ms |
26560 KiB |
| 04_handmade_01.txt |
AC |
232 ms |
26000 KiB |
| 04_handmade_02.txt |
AC |
213 ms |
25956 KiB |
| 04_handmade_03.txt |
AC |
191 ms |
18256 KiB |
| 04_handmade_04.txt |
AC |
194 ms |
18624 KiB |