結果
問題 |
No.1917 LCMST
|
ユーザー |
|
提出日時 | 2025-07-16 09:56:33 |
言語 | Rust (1.83.0 + proconio) |
結果 |
TLE
|
実行時間 | - |
コード長 | 6,277 bytes |
コンパイル時間 | 15,915 ms |
コンパイル使用メモリ | 397,840 KB |
実行使用メモリ | 7,716 KB |
最終ジャッジ日時 | 2025-07-16 09:57:14 |
合計ジャッジ時間 | 25,694 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 6 TLE * 1 -- * 35 |
ソースコード
#![allow(unused_imports,non_snake_case,dead_code)] use std::{cmp::Reverse as Rev,ops::Range,collections::*,iter::*}; use proconio::{marker::*,*}; // LCMST #[fastout] fn main(){ input!{ n:usize, a:[usize;n], } let divs=(0..n).map(|i|divisor(a[i])).collect::<Vec<_>>(); let mut it=0; let mut div_to_id=HashMap::new(); let mut id_to_div=vec![]; for i in 0..n{ for &d in &divs[i]{ if !div_to_id.contains_key(&d){ div_to_id.insert(d,it); id_to_div.push(d); it+=1; } } } let mut div_set=vec![vec![];id_to_div.len()]; for i in 0..n{ for &d in &divs[i]{ let id=div_to_id[&d]; div_set[id].push(a[i]); } } type MultiSet=BTreeMap<usize,usize>; fn add(set:&mut MultiSet,a:usize){ *set.entry(a).or_insert(0)+=1; } #[track_caller] fn rem(set:&mut MultiSet,a:usize){ let e=set.get_mut(&a).unwrap(); *e-=1; if *e==0{ set.remove(&a); } } #[derive(Clone,Debug)] struct Queue{ d:usize, que:MultiSet, co_que:MultiSet, w:usize, } let init_que=|d:usize|{ let mut co_que=MultiSet::new(); let id=div_to_id[&d]; for &d in &div_set[id]{ add(&mut co_que,d); } Queue{ d, que:MultiSet::new(), co_que, w:!0, } }; let mut que=id_to_div.iter().map(|&d|init_que(d)).collect::<Vec<Queue>>(); let mut min=BTreeSet::new(); cap!{ #![&a:[usize],&mut que:[Queue],&divs:[Vec<usize>],&div_to_id:HashMap<usize,usize>,&mut min:BTreeSet<(usize,usize)>] // a[i]をprimとして確定させる fn mov(i:usize){ for &n in &divs[i]{ let id=div_to_id[&n]; let que=&mut que[id]; if que.w!=!0{ min.remove(&(que.w,que.d)); } add(&mut que.que,a[i]); rem(&mut que.co_que,a[i]); if !que.que.is_empty() && !que.co_que.is_empty(){ let m0=que.que.first_key_value().unwrap().0; let m1=que.co_que.first_key_value().unwrap().0; que.w=m0/que.d*m1; min.insert((que.w,que.d)); } else{ que.w=!0; } } } } let mut index=HashMap::new(); for i in 0..n{ index.entry(a[i]).or_insert(vec![]).push(i); } mov!(0); let mut ans=0; for _ in 1..n{ let (w,d)=min.first().unwrap(); ans+=w; let id=div_to_id[&d]; let new=*que[id].co_que.first_key_value().unwrap().0; let idx=index.get_mut(&new).unwrap().pop().unwrap(); mov!(idx); } println!("{ans}"); } // 約数列挙 // 小さい順になってる // 0はpanic fn divisor(n:usize)->Vec<usize>{ assert!(n!=0); let mut ret=vec![1]; for i in 2..{ if i*i>n{ break; } if n%i==0{ ret.push(i); } } for i in (0..ret.len()).rev(){ if ret[i]*ret[i]!=n{ ret.push(n/ret[i]); } } ret } #[macro_export] macro_rules! cap{ ()=>{}; (#![] $($fn:tt)*)=>{ cap!([],[],[],[],[$($fn)*],[],[]); }; (#![$($g:tt)*] $($fn:tt)*)=>{ cap!([$($g)*,],[],[],[],[$($fn)*],[],[]); }; ([$name:ident:$t:ty,$($rem:tt)*],[$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[$($fn:tt)*],[],[])=>{ cap!([$($rem)*],[$name:$t,$($ga)*],[$name,$($gn)*],[$name,$($ge)*],[$($fn)*],[],[]); }; ([$($flag:tt)? $name:ident:$t:ty,$($rem:tt)*],[$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[$($fn:tt)*],[],[])=>{ cap!([$($rem)*],[$name:$($flag)?$t,$($ga)*],[$name,$($gn)*],[$($flag)?$name,$($ge)*],[$($fn)*],[],[]); }; ([&mut $name:ident:$t:ty,$($rem:tt)*],[$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[$($fn:tt)*],[],[])=>{ cap!([$($rem)*],[$name:&mut $t,$($ga)*],[$name,$($gn)*],[&mut $name,$($ge)*],[$($fn)*],[],[]); }; ([],[$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[$(#[$($att:tt)*])? fn $name:ident($($arg:tt)*) $body:block $($rem:tt)*],[$($info:tt)*],[$($fn:tt)*])=>{ cap!([],[$($ga)*],[$($gn)*],[$($ge)*],[$($rem)*],[(($(#[$($att)*])?),$name,($($arg)*),(),$body),$($info)*],[$name,$($fn)*]); }; ([],[$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[$(#[$($att:tt)*])? fn $name:ident($($arg:tt)*)->$ret:ty $body:block $($rem:tt)*],[$($info:tt)*],[$($fn:tt)*])=>{ cap!([],[$($ga)*],[$($gn)*],[$($ge)*],[$($rem)*],[(($(#[$($att)*])?),$name,($($arg)*),$ret,$body),$($info)*],[$name,$($fn)*]); }; ([],[$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[],[$($info:tt)*],[$($fn:tt)*])=>{ cap!(@make_fn [$($ga)*],[$($gn)*],[$($ge)*],[$($info)*],[$($fn)*]); }; (@make_fn [$($ga:ident:$gt:ty,)*],[$($gn:tt)*],[$($ge:tt)*],[(($($att:tt)*),$name:ident,($($arg:tt)*),$ret:ty,$body:block),$($rem:tt)*],[$($fn:tt)*])=>{ $($att)* fn $name($($ga:$gt,)*$($arg)*)->$ret{ $(#[allow(unused_variables)] let $ga=$ga;)* cap!(@make_macros ($),[$($gn)*],[$($fn)*]); $body } cap!(@make_fn [$($ga:$gt,)*],[$($gn)*],[$($ge)*],[$($rem)*],[$($fn)*]); }; (@make_fn [$($ga:tt)*],[$($gn:tt)*],[$($ge:tt)*],[],[$($fn:tt)*])=>{ cap!(@make_global_macros ($),[$($ge)*],[$($fn)*]); }; (@make_macros ($dol:tt),[$($gn:ident,)*],[$name:ident,$($rem:tt)*])=>{ #[allow(unused_macros)] macro_rules! $name{ ($dol($dol arg:expr),*)=>{$name($($gn,)* $dol($dol arg),*)} } cap!(@make_macros ($),[$($gn,)*],[$($rem)*]); }; (@make_macros ($dol:tt),[$($gn:ident,)*],[])=>{}; (@make_global_macros ($dol:tt),[$($ge:expr,)*],[$name:ident,$($rem:tt)*])=>{ #[allow(unused_macros)] macro_rules! $name{ ($dol($dol arg:expr),*)=>{$name($($ge,)* $dol($dol arg),*)} } cap!(@make_global_macros ($),[$($ge,)*],[$($rem)*]); }; (@make_global_macros ($dol:tt),[$($ge:expr,)*],[])=>{}; }