// use rand::seq::SliceRandom; // use rand::Rng; fn get_line() -> String { let mut s = String::new(); std::io::stdin().read_line(&mut s).ok(); s.trim().to_string() } fn readln() -> T where T: std::str::FromStr, ::Err: std::fmt::Debug, { get_line().parse().unwrap() } trait Submitter { fn ask(&self, v: Vec) -> Vec; fn submit(&self, v: Vec); } struct JudgeSubmitter {} struct LocalSubmitter { n: i64, p: Vec, } impl Submitter for JudgeSubmitter { fn ask(&self, v: Vec) -> Vec { println!( "? {}", v.iter() .map(|x| x.to_string()) .collect::>() .join(" ") ); let ret: Vec = get_line() .split_whitespace() .map(|s| s.parse().unwrap()) .collect::>(); return ret; } fn submit(&self, v: Vec) { println!( "! {}", v.iter() .map(|x| x.to_string()) .collect::>() .join(" ") ); } } impl Submitter for LocalSubmitter { fn ask(&self, v: Vec) -> Vec { let mut ret = vec![self.p[0]; self.n as usize]; for i in 1..self.n as usize { ret[i] = if v[i] == 0 { std::cmp::min(ret[i - 1], self.p[i]) } else { std::cmp::max(ret[i - 1], self.p[i]) }; } return ret; } fn submit(&self, p: Vec) { if p != self.p { println!("---- ERROR ----"); println!("cor = {:?}\nyou = {:?}", self.p, p); } } } fn solve(n: i64, submitter: &dyn Submitter) { let mut ans = vec![-1; n as usize]; let vp = (0..n).map(|x| x & 1).collect::>(); let up = submitter.ask(vp); let vm = (0..n).map(|x| (x + 1) & 1).collect::>(); let dw = submitter.ask(vm); let mut used = vec![false; n as usize]; for i in 1..n as usize { if up[i - 1] != up[i] { ans[i] = up[i]; used[ans[i] as usize - 1] = true } if dw[i - 1] != dw[i] { ans[i] = dw[i]; used[ans[i] as usize - 1] = true } } let p = used.iter().enumerate().find(|(_, &b)| !b); if let Some(p) = p { ans[0] = p.0 as i64 + 1; } submitter.submit(ans); } fn main() { let t: i64 = readln(); for _ in 0..t { let n: i64 = readln(); let submitter: &dyn Submitter = &JudgeSubmitter {}; solve(n, submitter) } /* for _ in 0..100 { let mut rng = rand::thread_rng(); let n: i64 = rng.gen_range(1, 10); let mut p = (1..n + 1).collect::>(); p.shuffle(&mut rng); let submitter: &dyn Submitter = &LocalSubmitter { n, p }; solve(n, submitter); } */ } /* ------------- 以下マクロ -------------*/ pub mod io_pro { #[macro_export] macro_rules! input{ (sc=$sc:expr,$($r:tt)*)=>{ input_inner!{$sc,$($r)*} }; ($($r:tt)*)=>{ let mut sc=io_pro::Scanner::new(std::io::stdin().lock()); input_inner!{sc,$($r)*} }; } #[macro_export] macro_rules! input_inner{ ($sc:expr)=>{}; ($sc:expr,)=>{}; ($sc:expr,$var:ident:$t:tt$($r:tt)*)=>{ let $var=read_value!($sc,$t); input_inner!{$sc $($r)*} }; ($sc:expr,mut $var:ident:$t:tt$($r:tt)*)=>{ let mut $var=read_value!($sc,$t); input_inner!{$sc $($r)*} }; } #[macro_export] macro_rules! read_value{ ($sc:expr,($($t:tt),*))=>{ ($(read_value!($sc,$t)),*) }; ($sc:expr,[$t:tt;$len:expr])=>{ (0..$len).map(|_|read_value!($sc,$t)).collect::>() }; ($sc:expr,Chars)=>{read_value!($sc,String).chars().collect::>()}; ($sc:expr,Usize1)=>{read_value!($sc,usize)-1}; ($sc:expr,$t:ty)=>{$sc.next::<$t>()}; } pub struct Scanner { s: Box, input: std::str::SplitAsciiWhitespace<'static>, } impl Scanner { pub fn new(mut reader: R) -> Self { let s = { let mut s = String::new(); reader.read_to_string(&mut s).unwrap(); s.into_boxed_str() }; let mut sc = Scanner { s, input: "".split_ascii_whitespace(), }; use std::mem; let s: &'static str = unsafe { mem::transmute(&*sc.s) }; sc.input = s.split_ascii_whitespace(); sc } #[inline] pub fn next(&mut self) -> T where T::Err: std::fmt::Debug, { self.input .next() .unwrap() .parse::() .expect("Parse error") } } }