結果
| 問題 |
No.2743 Twisted Lattice
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-05-01 16:24:45 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 684 ms / 3,000 ms |
| コード長 | 3,117 bytes |
| コンパイル時間 | 14,017 ms |
| コンパイル使用メモリ | 377,480 KB |
| 実行使用メモリ | 45,836 KB |
| 最終ジャッジ日時 | 2024-11-21 21:36:53 |
| 合計ジャッジ時間 | 22,194 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 8 |
ソースコード
#![allow(unused_imports)]
//use itertools::{iproduct, Itertools};
use proconio::input;
use proconio::marker::*;
use std::collections::*;
fn main() {
input! {
_:usize,
_:usize,
n:usize,
ab:[(i64,i64);n],
}
let amb = ab.iter().map(|&(a, b)| a - b).collect::<Vec<_>>();
let apb = ab.iter().map(|&(a, b)| a + b).collect::<Vec<_>>();
let mut cums = BTreeMap::new();
let mut cums_rev = BTreeMap::new();
let mut cols = HashMap::new();
for i in 0..n {
cols.entry(ab[i].1).or_insert(vec![]).push(ab[i].0);
}
for vals in cols.values_mut() {
vals.sort();
}
let mut sorted_idx = (0..n).collect::<Vec<_>>();
sorted_idx.sort_by_key(|&i| ab[i].1);
let mut cum = INF;
for &i in sorted_idx.iter() {
cum = cum.min(amb[i]);
cums.insert(ab[i].1, cum);
}
sorted_idx.reverse();
cum = INF;
for &i in sorted_idx.iter() {
cum = cum.min(apb[i]);
cums_rev.insert(ab[i].1, cum);
}
for i in 0..n {
let mut ans = INF;
if let Some((_, &cmb)) = cums.range(..=ab[i].1 - 2).last() {
ans = ans.min(apb[i] + cmb - 2);
}
if let Some((_, &cpb)) = cums_rev.range(ab[i].1 + 2..).next() {
ans = ans.min(amb[i] + cpb - 2);
}
if let Some(&c) = cols.get(&(ab[i].1 - 1)).map(|xs| xs.first().unwrap()) {
ans = ans.min(ab[i].0.max(c));
}
if let Some(&c) = cols.get(&(ab[i].1 + 1)).map(|xs| xs.first().unwrap()) {
ans = ans.min(ab[i].0.max(c));
}
if let Some(cand) = cols.get(&ab[i].1).map(|xs| {
let id = xs.lower_bound(ab[i].0 + 1);
let mut res = INF;
if id < xs.len() {
res = res.min(xs[id] - ab[i].0);
}
let id = xs.upper_bound(ab[i].0 - 1);
if !0 != id {
res = res.min(ab[i].0 - xs[id]);
}
res
}) {
ans = ans.min(cand);
}
println!("{}", ans);
}
}
const INF: i64 = std::i64::MAX;
use crate::bound::Bound;
mod bound {
pub trait Bound<T> {
fn lower_bound(&self, val: T) -> usize;
fn upper_bound(&self, val: T) -> usize;
}
impl<T> Bound<T> for [T]
where
T: Ord + Copy,
{
fn lower_bound(&self, val: T) -> usize {
let mut ok = self.len();
let mut ng = !0;
while ok.wrapping_sub(ng) > 1 {
let m = ok.wrapping_add(ng) / 2;
if val <= self[m] {
ok = m;
} else {
ng = m;
}
}
ok
}
fn upper_bound(&self, val: T) -> usize {
let mut ok = !0;
let mut ng = self.len();
while ng.wrapping_sub(ok) > 1 {
let m = ng.wrapping_add(ok) / 2;
if self[m] <= val {
ok = m;
} else {
ng = m;
}
}
ok
}
}
}