結果
| 問題 |
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,)*],[])=>{};
}