結果
問題 | No.1370 置換門松列 |
ユーザー |
![]() |
提出日時 | 2021-01-29 22:06:27 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 25 ms / 2,000 ms |
コード長 | 6,001 bytes |
コンパイル時間 | 26,756 ms |
コンパイル使用メモリ | 398,308 KB |
実行使用メモリ | 10,036 KB |
最終ジャッジ日時 | 2024-09-14 19:20:26 |
合計ジャッジ時間 | 26,518 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge6 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 25 |
コンパイルメッセージ
warning: unused variable: `len` --> src/main.rs:180:10 | 180 | let (len, id) = scc.build(); | ^^^ help: if this is intentional, prefix it with an underscore: `_len` | = note: `#[warn(unused_variables)]` on by default
ソースコード
fn kadomatsu(a: &[usize]) -> bool {a[0] != a[1] && a[1] != a[2] && a[2] != a[0] && (a[1] > a[0].max(a[2]) || a[1] < a[0].min(a[2]))}// ---------- begin SCC ----------pub struct SCC {size: usize,edge: Vec<(u32, u32)>,}impl SCC {pub fn new(size: usize) -> Self {assert!(size <= 10usize.pow(8));SCC { size, edge: vec![] }}pub fn add_edge(&mut self, a: usize, b: usize) {assert!(a < self.size && b < self.size);self.edge.push((a as u32, b as u32));}pub fn build(&self) -> (usize, Vec<usize>) {let size = self.size;let mut start = vec![0u32; size + 1];self.edge.iter().for_each(|e| start[e.0 as usize + 1] += 1);for i in 1..=size {start[i] += start[i - 1];}let mut buf = vec![0; self.edge.len()];for &(a, b) in self.edge.iter() {let po = &mut start[a as usize];buf[*po as usize] = b;*po += 1;}let mut s = 0usize;let mut neighbor = start.into_iter().take(size).map(|t| {let t = t as usize;let it = buf[s..t].iter().map(|p| *p as usize);s = t;it}).collect::<Vec<_>>();let mut ord = vec![size; size];let mut assigned = vec![false; size];let mut stack_s = vec![];let mut stack_p = vec![];let mut call = vec![];let mut now_ord = 0;let mut res = vec![0; size];let mut id = 0;enum Operation {Call(usize),Iter(usize),Eval(usize),}for i in 0..size {if ord[i] != size {continue;}call.push(Operation::Call(i));while let Some(op) = call.pop() {match op {Operation::Call(v) => {ord[v] = now_ord;now_ord += 1;stack_s.push(v);stack_p.push(v);call.push(Operation::Eval(v));call.push(Operation::Iter(v));}Operation::Iter(v) => {let it = &mut neighbor[v];while let Some(u) = it.next() {if ord[u] == size {call.push(Operation::Iter(v));call.push(Operation::Call(u));break;} else if !assigned[u] {while ord[*stack_p.last().unwrap()] > ord[u] {stack_p.pop();}}}}Operation::Eval(v) => {if *stack_p.last().unwrap() == v {while let Some(u) = stack_s.pop() {res[u] = id;assigned[u] = true;if u == v {break;}}stack_p.pop();id += 1;}}}}}res.iter_mut().for_each(|v| *v = id - 1 - *v);(id, res)}}// ---------- end SCC ----------// ---------- begin input macro ----------// reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8macro_rules! input {(source = $s:expr, $($r:tt)*) => {let mut iter = $s.split_whitespace();input_inner!{iter, $($r)*}};($($r:tt)*) => {let s = {use std::io::Read;let mut s = String::new();std::io::stdin().read_to_string(&mut s).unwrap();s};let mut iter = s.split_whitespace();input_inner!{iter, $($r)*}};}macro_rules! input_inner {($iter:expr) => {};($iter:expr, ) => {};($iter:expr, $var:ident : $t:tt $($r:tt)*) => {let $var = read_value!($iter, $t);input_inner!{$iter $($r)*}};}macro_rules! read_value {($iter:expr, ( $($t:tt),* )) => {( $(read_value!($iter, $t)),* )};($iter:expr, [ $t:tt ; $len:expr ]) => {(0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()};($iter:expr, chars) => {read_value!($iter, String).chars().collect::<Vec<char>>()};($iter:expr, bytes) => {read_value!($iter, String).bytes().collect::<Vec<u8>>()};($iter:expr, usize1) => {read_value!($iter, usize) - 1};($iter:expr, $t:ty) => {$iter.next().unwrap().parse::<$t>().expect("Parse error")};}// ---------- end input macro ----------fn run() {input! {n: usize,m: usize,a: [usize1; n],}if a.windows(2).any(|a| a[0] == a[1]) {println!("No");return;}let mut scc = SCC::new(m);for (i, a) in a.windows(3).enumerate() {if a[0] == a[2] {println!("No");return;}if i & 1 == 0 {scc.add_edge(a[1], a[0]);scc.add_edge(a[1], a[2]);} else {scc.add_edge(a[0], a[1]);scc.add_edge(a[2], a[1]);}}let (len, id) = scc.build();let p = (1..=m).collect::<Vec<_>>();for a in a.windows(3) {if !kadomatsu(&[p[id[a[0]]], p[id[a[1]]], p[id[a[2]]]]) {println!("No");return;}}println!("Yes");let mut s = String::new();for k in 0..m {s.push_str(&format!("{} ", p[id[k]]));}s.pop();println!("{}", s);}fn main() {run();}