結果
| 問題 |
No.2796 Small Matryoshka
|
| コンテスト | |
| ユーザー |
naut3
|
| 提出日時 | 2024-06-28 21:47:24 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,301 bytes |
| コンパイル時間 | 24,385 ms |
| コンパイル使用メモリ | 399,760 KB |
| 実行使用メモリ | 29,228 KB |
| 最終ジャッジ日時 | 2024-06-28 21:47:54 |
| 合計ジャッジ時間 | 14,720 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 8 WA * 11 |
ソースコード
#![allow(non_snake_case, unused_imports)]
use monoid::Max;
use proconio::{fastout, input, marker::*};
#[fastout]
fn main() {
input! {
N: usize,
mut rR: [(usize, usize); N],
}
let mut v = vec![0];
for &(r, R) in rR.iter() {
v.push(r);
v.push(R);
}
let (z, zi) = coordinate_compression(&v);
let mut stree: segment_tree::SegmentTree<Max<usize>> = segment_tree::SegmentTree::new(z.len());
rR.sort_by_key(|&(r, _)| r);
for (r, R) in rR {
let (_, &k) = zi.range(..=r).next_back().unwrap();
let p = *zi.get(&R).unwrap();
let v = stree.prod(..=k);
if stree.get(p) <= v + 1 {
stree.update(p, v + 1);
}
}
let ans = N - stree.prod(..);
println!("{}", ans);
}
pub fn coordinate_compression<T: std::cmp::Ord + Clone + Copy>(
values: &[T],
) -> (Vec<T>, std::collections::BTreeMap<T, usize>) {
let s: std::collections::BTreeSet<T> = values.iter().cloned().collect();
let z: Vec<T> = s.iter().cloned().collect();
let zinv: std::collections::BTreeMap<T, usize> =
z.iter().enumerate().map(|(i, &v)| (v, i)).collect();
(z, zinv)
}
pub mod monoid {
pub trait Monoid {
type S; // 集合
fn op(lhs: &Self::S, rhs: &Self::S) -> Self::S; // 二項演算
const E: Self::S; // 単位元
}
pub struct Add<T> {
_marker: std::marker::PhantomData<T>,
}
pub struct Max<T> {
_marker: std::marker::PhantomData<T>,
}
pub struct Min<T> {
_marker: std::marker::PhantomData<T>,
}
pub struct Update<T> {
_marker: std::marker::PhantomData<T>,
}
macro_rules! impl_primitives {
($($t: ty), *) => {
$(
impl Monoid for Add<$t> {
type S = $t;
const E: Self::S = 0;
fn op(lhs: &Self::S, rhs: &Self::S) -> Self::S {
lhs + rhs
}
}
impl Monoid for Max<$t> {
type S = $t;
const E: Self::S = <$t>::MIN;
fn op(lhs: &Self::S, rhs: &Self::S) -> Self::S {
std::cmp::max(*lhs, *rhs)
}
}
impl Monoid for Min<$t> {
type S = $t;
const E: Self::S = <$t>::MAX;
fn op(lhs: &Self::S, rhs: &Self::S) -> Self::S {
std::cmp::min(*lhs, *rhs)
}
}
impl Monoid for Update<$t> {
type S = $t;
const E: Self::S = <$t>::MAX;
fn op(_: &Self::S, rhs: &Self::S) -> Self::S {
*rhs
}
}
)*
};
}
impl_primitives!(usize, isize, u128, i128, u64, i64);
}
pub mod segment_tree {
use crate::monoid::Monoid;
pub struct SegmentTree<M: Monoid> {
size: usize,
tree: Vec<M::S>,
}
impl<M: Monoid<S = S>, S: Clone + Copy> SegmentTree<M> {
/// self = [e; size]
pub fn new(size: usize) -> Self {
Self {
size,
tree: vec![M::E; size << 1],
}
}
/// self = array
pub fn from(array: &[M::S]) -> Self {
let size = array.len();
let mut tree = vec![M::E; size << 1];
for i in 0..size {
tree[i + size] = array[i];
}
for i in (1..size).rev() {
tree[i] = M::op(&tree[i << 1], &tree[i << 1 | 1]);
}
return Self { size, tree };
}
/// self[i] <- s
pub fn update(&mut self, mut i: usize, s: S) {
i += self.size;
self.tree[i] = s;
while i > 1 {
i >>= 1;
self.tree[i] = M::op(&self.tree[i << 1], &self.tree[i << 1 | 1]);
}
}
/// get self[i]
pub fn get(&self, i: usize) -> S {
return self.tree[i + self.size];
}
/// calculate Π_{i ∈ range} self[i]
pub fn prod<R: std::ops::RangeBounds<usize>>(&self, range: R) -> S {
let left = match range.start_bound() {
std::ops::Bound::Included(&l) => l,
std::ops::Bound::Excluded(&l) => l + 1,
std::ops::Bound::Unbounded => 0,
};
let right = match range.end_bound() {
std::ops::Bound::Included(&r) => r + 1,
std::ops::Bound::Excluded(&r) => r,
std::ops::Bound::Unbounded => self.size,
};
return self._prod(left, right);
}
fn _prod(&self, mut left: usize, mut right: usize) -> S {
left += self.size;
right += self.size;
let (mut sl, mut sr) = (M::E, M::E);
while left < right {
if left & 1 == 1 {
sl = M::op(&sl, &self.tree[left]);
left += 1;
}
if right & 1 == 1 {
right -= 1;
sr = M::op(&self.tree[right], &sr);
}
left >>= 1;
right >>= 1;
}
return M::op(&sl, &sr);
}
}
}
naut3