結果
問題 |
No.1917 LCMST
|
ユーザー |
|
提出日時 | 2025-07-16 10:24:54 |
言語 | Rust (1.83.0 + proconio) |
結果 |
MLE
|
実行時間 | - |
コード長 | 10,260 bytes |
コンパイル時間 | 12,552 ms |
コンパイル使用メモリ | 398,560 KB |
実行使用メモリ | 812,928 KB |
最終ジャッジ日時 | 2025-07-16 10:27:05 |
合計ジャッジ時間 | 112,601 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 32 TLE * 1 MLE * 8 -- * 1 |
ソースコード
#![allow(unused_imports,non_snake_case,dead_code)] use std::{cmp::Reverse as Rev,ops::Range,collections::*,iter::*}; use proconio::{marker::*,*}; // LCMST type HashMap<K,V>=rustc_hash::FxHashMap<K,V>; #[fastout] fn main(){ input!{ n:usize, a:[usize;n], } let mut era=vec![!0;1e6 as usize+5]; for i in 2..era.len(){ if era[i]!=!0{ continue; } for j in 1..{ if era.len()<=i*j{ break; } era[i*j]=i; } } let divisor=|mut n:usize|->Vec<usize>{ let mut ps=vec![]; while era[n]!=!0{ let p=era[n]; let mut cnt=0; while n%p==0{ cnt+=1; n/=p; } ps.push((p,cnt)); } if n!=1{ ps.push((n,1)); } fn rec(ps:&[(usize,usize)],i:usize,mut div:usize,divs:&mut Vec<usize>){ if i==!0{ divs.push(div); return; } let (p,cnt)=ps[i]; for _ in 0..=cnt{ rec(ps,i-1,div,divs); div*=p; } } let mut divs=vec![]; rec(&ps,ps.len()-1,1,&mut divs); divs }; let divs=(0..n).map(|i|divisor(a[i])).collect::<Vec<_>>(); let mut id_to_div=divs.iter().flatten().copied().collect::<Vec<_>>(); id_to_div.sort_unstable(); id_to_div.dedup(); let mut div_to_id=HashMap::default(); for i in 0..id_to_div.len(){ div_to_id.insert(id_to_div[i],i); } 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]); } } for i in 0..div_set.len(){ div_set[i].sort_unstable_by_key(|&t|!t); } // type MultiSet=BTreeMap<usize,usize>; // fn add(set:&mut MultiSet,a:usize){ // *set.entry(a).or_insert(0)+=1; // } // 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:usize, co_que:Vec<usize>, w:usize, } let init_que=|d:usize|{ let id=div_to_id[&d]; Queue{ d, que:!0, co_que:div_set[id].clone(), w:!0, } }; let mut cnt=vec![0;1e6 as usize+5]; for i in 0..n{ cnt[a[i]]+=1; } 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:rustc_hash::FxHashMap<usize,usize>, &mut min:BTreeSet<(usize,usize)>,&mut cnt:[usize]] // a[i]をprimとして確定させる fn mov(i:usize){ cnt[a[i]]-=1; 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)); } que.que=que.que.min(a[i]); while let Some(&v)=que.co_que.last(){ if cnt[v]==0{ que.co_que.pop().unwrap(); } else{ break; } } if que.que!=!0 && !que.co_que.is_empty(){ let m0=que.que; let m1=que.co_que.last().unwrap(); que.w=m0/que.d*m1; min.insert((que.w,que.d)); } else{ que.w=!0; } } } } let mut index=HashMap::default(); 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.last().unwrap(); let idx=index.get_mut(&new).unwrap().pop().unwrap(); mov!(idx); } println!("{ans}"); } #[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,)*],[])=>{}; } mod rustc_hash{ use core::convert::TryInto; use core::default::Default; use core::hash::BuildHasherDefault; use core::hash::Hasher; use core::mem::size_of; use core::ops::BitXor; use std::collections::{HashMap, HashSet}; pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>; pub type FxHashSet<V> = HashSet<V, BuildHasherDefault<FxHasher>>; pub struct FxHasher { hash: usize, } #[cfg(target_pointer_width = "32")] const K: usize = 0x9e3779b9; #[cfg(target_pointer_width = "64")] const K: usize = 0x517cc1b727220a95; impl Default for FxHasher { #[inline] fn default() -> FxHasher { FxHasher { hash: 0 } } } impl FxHasher { #[inline] fn add_to_hash(&mut self, i: usize) { self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K); } } impl Hasher for FxHasher { #[inline] fn write(&mut self, mut bytes: &[u8]) { #[cfg(target_pointer_width = "32")] let read_usize = |bytes: &[u8]| u32::from_ne_bytes(bytes[..4].try_into().unwrap()); #[cfg(target_pointer_width = "64")] let read_usize = |bytes: &[u8]| u64::from_ne_bytes(bytes[..8].try_into().unwrap()); let mut hash = FxHasher { hash: self.hash }; assert!(size_of::<usize>() <= 8); while bytes.len() >= size_of::<usize>() { hash.add_to_hash(read_usize(bytes) as usize); bytes = &bytes[size_of::<usize>()..]; } if (size_of::<usize>() > 4) && (bytes.len() >= 4) { hash.add_to_hash(u32::from_ne_bytes(bytes[..4].try_into().unwrap()) as usize); bytes = &bytes[4..]; } if (size_of::<usize>() > 2) && bytes.len() >= 2 { hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as usize); bytes = &bytes[2..]; } if (size_of::<usize>() > 1) && bytes.len() >= 1 { hash.add_to_hash(bytes[0] as usize); } self.hash = hash.hash; } #[inline] fn write_u8(&mut self, i: u8) { self.add_to_hash(i as usize); } #[inline] fn write_u16(&mut self, i: u16) { self.add_to_hash(i as usize); } #[inline] fn write_u32(&mut self, i: u32) { self.add_to_hash(i as usize); } #[cfg(target_pointer_width = "32")] #[inline] fn write_u64(&mut self, i: u64) { self.add_to_hash(i as usize); self.add_to_hash((i >> 32) as usize); } #[cfg(target_pointer_width = "64")] #[inline] fn write_u64(&mut self, i: u64) { self.add_to_hash(i as usize); } #[inline] fn write_usize(&mut self, i: usize) { self.add_to_hash(i); } #[inline] fn finish(&self) -> u64 { self.hash as u64 } } }