結果
| 問題 |
No.1917 LCMST
|
| コンテスト | |
| ユーザー |
hiromi_ayase
|
| 提出日時 | 2022-04-30 06:33:36 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 378 ms / 4,000 ms |
| コード長 | 5,284 bytes |
| コンパイル時間 | 16,596 ms |
| コンパイル使用メモリ | 380,208 KB |
| 実行使用メモリ | 49,700 KB |
| 最終ジャッジ日時 | 2024-06-29 12:35:59 |
| 合計ジャッジ時間 | 22,615 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 42 |
ソースコード
use std::collections::{HashMap, HashSet};
#[allow(clippy::many_single_char_names)]
fn main() {
let n = getline().parse::<usize>().unwrap();
let a = getline()
.split(' ')
.map(|x| x.parse::<i32>().unwrap())
.collect::<Vec<_>>();
let mut ans = 0;
let mut set = HashSet::new();
for i in 0..n {
if set.contains(&a[i]) {
ans += a[i] as i64;
continue;
}
set.insert(a[i]);
}
let mut a: Vec<i32> = set.into_iter().collect();
let n = a.len();
a.sort();
let mut div_map: HashMap<i32, _> = HashMap::new();
for i in 0..n as i32 {
let divs = divisors(a[i as usize]);
for d in divs {
div_map.entry(d).or_insert_with(Vec::new).push(i);
}
}
let mut edges: Vec<(i32, i32, i64)> = Vec::new();
for e in div_map {
let d = e.0 as i64;
let u = e.1[0];
for v in e.1 {
if u == v {
continue;
}
edges.push((u, v, a[u as usize] as i64 / d * a[v as usize] as i64));
}
}
edges.sort_by_key(|e| e.2);
let mut ds = Dsu::new(n);
for e in edges {
if ds.same(e.0 as usize, e.1 as usize) {
continue;
}
ds.merge(e.0 as usize, e.1 as usize);
ans += e.2;
}
println!("{}", ans);
}
fn divisors(x: i32) -> Vec<i32> {
let mut ret = vec![];
let mut i = 1;
while i * i <= x {
if x % i == 0 {
ret.push(i);
if i * i != x {
ret.push(x / i);
}
}
i += 1;
}
ret
}
fn getline() -> String {
let mut buf = String::new();
std::io::stdin().read_line(&mut buf).unwrap();
buf.trim().to_string()
}
pub struct Dsu {
n: usize,
// root node: -1 * component size
// otherwise: parent
parent_or_size: Vec<i32>,
}
impl Dsu {
/// Creates a new `Dsu`.
///
/// # Constraints
///
/// - $0 \leq n \leq 10^8$
///
/// # Complexity
///
/// - $O(n)$
pub fn new(size: usize) -> Self {
Self {
n: size,
parent_or_size: vec![-1; size],
}
}
// `\textsc` does not work in KaTeX
/// Performs the Uɴɪᴏɴ operation.
///
/// # Constraints
///
/// - $0 \leq a < n$
/// - $0 \leq b < n$
///
/// # Panics
///
/// Panics if the above constraints are not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
pub fn merge(&mut self, a: usize, b: usize) -> usize {
assert!(a < self.n);
assert!(b < self.n);
let (mut x, mut y) = (self.leader(a), self.leader(b));
if x == y {
return x;
}
if -self.parent_or_size[x] < -self.parent_or_size[y] {
std::mem::swap(&mut x, &mut y);
}
self.parent_or_size[x] += self.parent_or_size[y];
self.parent_or_size[y] = x as i32;
x
}
/// Returns whether the vertices $a$ and $b$ are in the same connected component.
///
/// # Constraints
///
/// - $0 \leq a < n$
/// - $0 \leq b < n$
///
/// # Panics
///
/// Panics if the above constraint is not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
pub fn same(&mut self, a: usize, b: usize) -> bool {
assert!(a < self.n);
assert!(b < self.n);
self.leader(a) == self.leader(b)
}
/// Performs the Fɪɴᴅ operation.
///
/// # Constraints
///
/// - $0 \leq a < n$
///
/// # Panics
///
/// Panics if the above constraint is not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
pub fn leader(&mut self, a: usize) -> usize {
assert!(a < self.n);
if self.parent_or_size[a] < 0 {
return a;
}
self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
self.parent_or_size[a] as usize
}
/// Returns the size of the connected component that contains the vertex $a$.
///
/// # Constraints
///
/// - $0 \leq a < n$
///
/// # Panics
///
/// Panics if the above constraint is not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
pub fn size(&mut self, a: usize) -> usize {
assert!(a < self.n);
let x = self.leader(a);
-self.parent_or_size[x] as usize
}
/// Divides the graph into connected components.
///
/// The result may not be ordered.
///
/// # Complexity
///
/// - $O(n)$
pub fn groups(&mut self) -> Vec<Vec<usize>> {
let mut leader_buf = vec![0; self.n];
let mut group_size = vec![0; self.n];
for i in 0..self.n {
leader_buf[i] = self.leader(i);
group_size[leader_buf[i]] += 1;
}
let mut result = vec![Vec::new(); self.n];
for i in 0..self.n {
result[i].reserve(group_size[i]);
}
for i in 0..self.n {
result[leader_buf[i]].push(i);
}
result
.into_iter()
.filter(|x| !x.is_empty())
.collect::<Vec<Vec<usize>>>()
}
}
hiromi_ayase