#![allow(non_snake_case)] #![allow(unused_imports)] #![allow(unused_macros)] #![allow(clippy::needless_range_loop)] #![allow(clippy::comparison_chain)] #![allow(clippy::nonminimal_bool)] #![allow(clippy::neg_multiply)] #![allow(dead_code)] // use itertools::Itertools; use std::cmp::Reverse; use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, VecDeque}; // use superslice::Ext; // use bitset_fixed::BitSet; use proconio::{ input, marker::{Chars, Usize1}, }; #[derive(Default)] struct Solver {} impl Solver { // #[fastout] fn solve(&mut self) { input! { N: usize, P: [usize; N] } let mut used = vec![false; N + 1]; let mut ans = vec![]; let mut linked_list = LinkedList::new(P); for pos in 1..=N { if ans.len() == N { break; } if used[pos] || linked_list.list[&pos].back.is_none() { continue; } ans.push(pos); used[pos] = true; if let Some(nxt) = linked_list.list[&pos].back { ans.push(nxt); used[nxt] = true; linked_list.remove(pos); linked_list.remove(nxt); } } println!("{}", join_to_string(&ans, " ")); } } fn join_to_string(v: &[T], sep: &str) -> String { v.iter() .fold("".to_string(), |s, x| s + x.to_string().as_str() + sep) } #[derive(Debug)] struct LinkedNode { front: Option, back: Option, } #[derive(Debug)] struct LinkedList { list: HashMap, } impl LinkedList { fn new(v: Vec) -> Self { let mut list = HashMap::new(); if v.len() == 1 { list.insert( v[0], LinkedNode { front: None, back: None, }, ); } else if v.len() >= 2 { list.insert( v[0], LinkedNode { front: None, back: Some(v[1]), }, ); list.insert( v[v.len() - 1], LinkedNode { front: Some(v[v.len() - 2]), back: None, }, ); for i in 1..v.len() - 1 { list.insert( v[i], LinkedNode { front: Some(v[i - 1]), back: Some(v[i + 1]), }, ); } } LinkedList { list } } fn remove(&mut self, x: usize) { let front = self.list[&x].front; let back = self.list[&x].back; if let Some(front) = front { if let Some(v) = self.list.get_mut(&front) { v.back = back; } } if let Some(back) = back { if let Some(v) = self.list.get_mut(&back) { v.front = front; } } self.list.remove(&x); } // xの直後にyを挿入 fn insert(&mut self, x: usize, y: usize) { self.list.insert( y, LinkedNode { front: Some(x), back: self.list[&x].back, }, ); if let Some(back) = self.list[&x].back { if let Some(v) = self.list.get_mut(&back) { v.front = Some(y); } } if let Some(v) = self.list.get_mut(&x) { v.back = Some(y); } } fn to_list(&self) -> Vec { let mut ret = vec![]; let mut now = { let mut head = 0; for (k, v) in self.list.iter() { if v.front.is_none() { head = *k; break; } } head }; loop { ret.push(now); if let Some(x) = self.list[&now].back { now = x; } else { break; } } ret } } fn main() { std::thread::Builder::new() .stack_size(128 * 1024 * 1024) .spawn(|| Solver::default().solve()) .unwrap() .join() .unwrap(); }