結果
問題 |
No.3147 Parentheses Modification and Rotation (RM Ver.)
|
ユーザー |
|
提出日時 | 2025-05-17 02:22:00 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 5 ms / 2,000 ms |
コード長 | 18,810 bytes |
コンパイル時間 | 15,337 ms |
コンパイル使用メモリ | 388,208 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-05-17 02:22:18 |
合計ジャッジ時間 | 14,753 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 33 |
コンパイルメッセージ
warning: unused import: `map::hmap` --> src/main.rs:397:13 | 397 | pub use map::hmap; | ^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `map::vmap` --> src/main.rs:398:13 | 398 | pub use map::vmap; | ^^^^^^^^^ warning: unused import: `vec2::vec2` --> src/main.rs:402:13 | 402 | pub use vec2::vec2; | ^^^^^^^^^^ warning: unused import: `vecs::hvec` --> src/main.rs:403:13 | 403 | pub use vecs::hvec; | ^^^^^^^^^^ warning: unused import: `vecs::vvec` --> src/main.rs:404:13 | 404 | pub use vecs::vvec; | ^^^^^^^^^^
ソースコード
use proconio::input; use std::collections::VecDeque; fn main() { input! { _n: usize, s: String, r: i64, m: i64, } let a = s .chars() .rev() .map(|c| match c { '(' => -1, ')' => 1, _ => unreachable!(), }) .collect::<Vec<_>>(); let mut deque = VecDeque::<Event>::new(); let mut start_value = 0; let mut end_value = 0; for (i, &x) in a.iter().enumerate() { end_value += x; while let Some(&Event { time: _, value }) = deque.front() { if end_value <= value { deque.pop_back(); } else { break; } } deque.push_back(Event { time: i, value: end_value, }); } let ans = if (end_value - start_value) % 2 == 0 { std::iter::once((start_value, deque.front().unwrap().value, end_value)) .chain(a.iter().enumerate().map(|(i, &x)| { start_value += x; end_value += x; while let Some(&Event { time, value: _ }) = deque.front() { if time < i { deque.pop_front(); } else { break; } } while let Some(&Event { time: _, value }) = deque.front() { if end_value <= value { deque.pop_back(); } else { break; } } deque.push_back(Event { time: s.len() + i, value: end_value, }); (start_value, deque.front().unwrap().value, end_value) })) .enumerate() .map(|(i, (x, y, z))| ((x - y + 1) / 2 + (z - y + 1) / 2) * m + i as i64 * r) .min() .unwrap() } else { -1 }; println!("{ans}"); } #[derive(Debug, Clone, Copy)] struct Event { time: usize, value: i64, } // lg {{{ // https://ngtkana.github.io/ac-adapter-rs/lg/index.html #[allow(dead_code)] mod lg { mod map { use crate::lg::align_of; use crate::lg::format; use crate::lg::table::Align; use crate::lg::table::Cell; use crate::lg::table::Table; use std::collections; use std::collections::BTreeMap; use std::collections::HashMap; use std::fmt; use std::iter; use std::slice; use std::vec; pub fn vmap<'a, K, V, M>(title: &str, map: M) -> Table where M: Copy + Map<'a, K = K, V = V>, K: fmt::Debug, V: fmt::Debug, { Table { table: iter::once(vec![ Cell { text: String::new(), align: Align::Left, }, Cell { text: title.to_string(), align: Align::Center, }, ]) .chain(map.map_iter().map(|(k, v)| { let v = format(&v); vec![ Cell { text: format(&k), align: Align::Center, }, Cell { align: align_of(&v), text: v, }, ] })) .collect(), } } pub fn hmap<'a, K, V, M>(title: &str, map: M) -> Table where M: Copy + Map<'a, K = K, V = V>, K: fmt::Debug, V: fmt::Debug, { Table { table: vec![ iter::once(Cell { text: String::new(), align: Align::Left, }) .chain(map.map_iter().map(|(k, _)| Cell { text: format(&k), align: Align::Center, })) .collect(), iter::once(Cell { text: title.to_string(), align: Align::Left, }) .chain(map.map_iter().map(|(_, v)| { let v = format(&v); Cell { align: align_of(&v), text: v, } })) .collect(), ], } } pub fn deconstruct_ref_tuple<K, V>((k, v): &(K, V)) -> (&K, &V) { (k, v) } pub trait Map<'a>: 'a { type K; type V; type I: Iterator<Item = (&'a Self::K, &'a Self::V)>; fn map_iter(self) -> Self::I; } impl<'a, K, V, S> Map<'a> for &'a HashMap<K, V, S> { type I = collections::hash_map::Iter<'a, K, V>; type K = K; type V = V; fn map_iter(self) -> Self::I { self.iter() } } impl<'a, K, V> Map<'a> for &'a BTreeMap<K, V> { type I = collections::btree_map::Iter<'a, K, V>; type K = K; type V = V; fn map_iter(self) -> Self::I { self.iter() } } impl<'a, K, V> Map<'a> for &'a [(K, V)] { type I = iter::Map<slice::Iter<'a, (K, V)>, fn(&(K, V)) -> (&K, &V)>; type K = K; type V = V; fn map_iter(self) -> Self::I { self.iter().map(deconstruct_ref_tuple) } } impl<'a, K, V> Map<'a> for &'a Vec<(K, V)> { type I = iter::Map<slice::Iter<'a, (K, V)>, fn(&(K, V)) -> (&K, &V)>; type K = K; type V = V; fn map_iter(self) -> Self::I { self.iter().map(deconstruct_ref_tuple) } } impl<'a, const N: usize, K, V> Map<'a> for &'a [(K, V); N] { type I = iter::Map<slice::Iter<'a, (K, V)>, fn(&(K, V)) -> (&K, &V)>; type K = K; type V = V; fn map_iter(self) -> Self::I { self.iter().map(deconstruct_ref_tuple) } } } mod table { use core::fmt; const GRAY: &str = "\x1b[48;2;127;127;127;37m"; const RESET: &str = "\x1b[0m"; pub struct Table { pub table: Vec<Vec<Cell>>, } pub struct Cell { pub text: String, pub align: Align, } pub enum Align { Left, Center, Right, } impl fmt::Display for Table { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { struct ColumnFormat<'a> { pre: &'a str, width: usize, post: &'a str, } let Self { table } = self; let w = table[0].len(); assert!(table.iter().all(|row| row.len() == w)); let column_format = (0..w) .map(|j| ColumnFormat { pre: " ", width: table .iter() .map(|row| row[j].text.len().max(1)) .max() .unwrap(), post: if j == 0 { " │" } else { " " }, }) .collect::<Vec<_>>(); for (i, row) in table.iter().enumerate() { if i == 0 { write!(f, "{GRAY}")?; } for (&ColumnFormat { pre, width, post }, Cell { text, align }) in column_format.iter().zip(row) { write!(f, "{pre}")?; match align { Align::Left => write!(f, "{text:<width$}")?, Align::Center => write!(f, "{text:^width$}")?, Align::Right => write!(f, "{text:>width$}")?, } write!(f, "{post}")?; } if i == 0 { write!(f, "{RESET}")?; } writeln!(f)?; } Ok(()) } } } mod vec2 { use crate::lg::align_of; use crate::lg::format; use crate::lg::table::Align; use crate::lg::table::Cell; use crate::lg::table::Table; use std::fmt; use std::iter; pub fn vec2<'a, T, R, S>(title: &str, vec2: &'a S) -> Table where T: fmt::Debug + 'a, R: ?Sized, &'a R: Copy + IntoIterator<Item = &'a T> + 'a, &'a S: Copy + IntoIterator<Item = &'a R>, { let w = vec2 .into_iter() .map(|row| row.into_iter().count()) .max() .unwrap(); Table { table: iter::once( iter::once(Cell { text: title.to_string(), align: Align::Left, }) .chain((0..w).map(|i| Cell { text: i.to_string(), align: Align::Center, })) .collect(), ) .chain(vec2.into_iter().enumerate().map(|(j, row)| { iter::once(Cell { text: j.to_string(), align: Align::Center, }) .chain(row.into_iter().map(|v| { let v = format(&v); Cell { align: align_of(&v), text: v, } })) .chain(iter::repeat_with(|| Cell { text: String::new(), align: Align::Left, })) .take(1 + w) .collect() })) .collect(), } } } mod vecs { use super::table::Cell; use super::table::Table; use crate::lg::align_of; use crate::lg::table::Align; use std::iter; pub fn hvec(vecs: &[(String, Vec<String>)]) -> Table { let w = vecs.iter().map(|(_, row)| row.len()).max().unwrap(); Table { table: iter::once( iter::once(Cell { text: String::new(), align: Align::Left, }) .chain((0..w).map(|i| Cell { text: i.to_string(), align: Align::Center, })) .collect(), ) .chain(vecs.iter().map(|(title, row)| { iter::once(Cell { text: title.to_string(), align: Align::Center, }) .chain(row.iter().map(|v| Cell { align: align_of(v), text: v.clone(), })) .chain(iter::repeat_with(|| Cell { text: String::new(), align: Align::Left, })) .take(1 + w) .collect() })) .collect(), } } pub fn vvec(vecs: &[(String, Vec<String>)]) -> Table { let h = vecs.iter().map(|(_, col)| col.len()).max().unwrap(); Table { table: iter::once( iter::once(Cell { text: String::new(), align: Align::Center, }) .chain(vecs.iter().map(|(title, _)| Cell { text: title.to_string(), align: Align::Center, })) .collect(), ) .chain((0..h).map(|i| { iter::once(Cell { text: i.to_string(), align: Align::Center, }) .chain(vecs.iter().map(|(_, vec)| { let v = vec.get(i).map_or("", String::as_str); Cell { align: align_of(v), text: v.to_string(), } })) .collect() })) .collect(), } } } pub use map::hmap; pub use map::vmap; use std::borrow::Borrow; use std::fmt; use table::Align; pub use vec2::vec2; pub use vecs::hvec; pub use vecs::vvec; pub fn bools<B, I>(iter: I) -> String where B: Borrow<bool>, I: IntoIterator<Item = B>, { format!( "[{}]", iter.into_iter() .map(|b| ['.', '#'][usize::from(*(b.borrow()))]) .collect::<String>(), ) } pub fn align_of(s: &str) -> Align { // To improve this: https://doc.rust-lang.org/reference/tokens.html#floating-point-literals match s.parse::<f64>() { Ok(_) => Align::Right, Err(_) => Align::Left, } } #[macro_export] macro_rules! lg { (@contents $head:expr $(, $tail:expr)*) => {{ $crate::__lg_internal!($head); $( eprint!(","); $crate::__lg_internal!($tail); )* eprintln!(); }}; ($($expr:expr),* $(,)?) => {{ eprint!("{} \u{276f}", line!()); $crate::lg!(@contents $($expr),*) }}; } #[doc(hidden)] #[macro_export] macro_rules! __lg_internal { ($value:expr) => {{ match $value { head => { eprint!(" {} = {}", stringify!($value), $crate::lg::format(&head)); } } }}; } #[macro_export] macro_rules! table { ($vec2:expr) => { eprint!( "{}", $crate::lg::vec2($crate::lg::remove_ampersand(stringify!($vec2)), $vec2) ); }; } #[macro_export] macro_rules! vmap { ($map:expr) => { eprint!( "{}", $crate::lg::vmap($crate::lg::remove_ampersand(stringify!($map)), $map) ); }; } #[macro_export] macro_rules! hmap { ($map:expr) => { eprint!( "{}", $crate::lg::hmap($crate::lg::remove_ampersand(stringify!($map)), $map) ); }; } #[macro_export] macro_rules! vvec { ($($(@field $field:ident)* $vecs:expr),+ $(,)?) => { let mut vecs = Vec::new(); $( let name = $crate::lg::remove_ampersand(stringify!($vecs)); #[allow(unused_mut, unused_assignments)] let mut has_field = false; $( #[allow(unused_mut, unused_assignments)] { let mut name = name.to_owned(); has_field = true; name.push_str("."); name.push_str(stringify!($field)); let values = (&$vecs).into_iter().map(|v| $crate::lg::format(&v.$field)).collect::<Vec<_>>(); vecs.push((name, values)) } )* if !has_field { let values = (&$vecs).into_iter().map(|v| $crate::lg::format(&v)).collect::<Vec<_>>(); vecs.push((name.to_owned(), values)) } )+ eprint!("{}", $crate::lg::vvec(&vecs)); }; } #[macro_export] macro_rules! hvec { ($($(@field $field:ident)* $vecs:expr),+ $(,)?) => { let mut vecs = Vec::new(); $( let name = $crate::lg::remove_ampersand(stringify!($vecs)); #[allow(unused_mut, unused_assignments)] let mut has_field = false; $( #[allow(unused_mut, unused_assignments)] { let mut name = name.to_owned(); has_field = true; name.push_str("."); name.push_str(stringify!($field)); let values = (&$vecs).into_iter().map(|v| $crate::lg::format(&v.$field)).collect::<Vec<_>>(); vecs.push((name, values)) } )* if !has_field { let values = (&$vecs).into_iter().map(|v| $crate::lg::format(&v)).collect::<Vec<_>>(); vecs.push((name.to_owned(), values)) } )+ eprint!("{}", $crate::lg::hvec(&vecs)); }; } pub fn remove_ampersand(mut s: &str) -> &str { while let Some(t) = s.strip_prefix('&') { s = t; } s } pub fn format<T: fmt::Debug>(t: &T) -> String { let s = format!("{t:?}") .replace("340282366920938463463374607431768211455", "*") // u128 .replace("170141183460469231731687303715884105727", "*") // i128 .replace("18446744073709551615", "*") // u64 .replace("9223372036854775807", "*") // i64 .replace("-9223372036854775808", "*") // i64 .replace("4294967295", "*") // u32 .replace("2147483647", "*") // i32 .replace("-2147483648", "*") // i32 .replace("None", "*") .replace("true", "#") .replace("false", "."); let mut s = s.as_str(); while s.starts_with("Some(") { s = s.strip_prefix("Some(").unwrap(); s = s.strip_suffix(')').unwrap(); } while s.len() > 2 && s.starts_with('"') && s.ends_with('"') { s = s.strip_prefix('"').unwrap(); s = s.strip_suffix('"').unwrap(); } s.to_owned() } } // }}}