Problem:
Score : 500 points

Problem Statement

Given are N positive integers A_1,...,A_N.

Consider positive integers B_1, ..., B_N that satisfy the following condition.

Condition: For any i, j such that 1 \leq i < j \leq N, A_i B_i = A_j B_j holds.

Find the minimum possible value of B_1 + ... + B_N for such B_1,...,B_N.

Since the answer can be enormous, print the sum modulo (10^9 +7).

Constraints

1 \leq N \leq 10^4

1 \leq A_i \leq 10^6

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 ... A_N

Output

Print the minimum possible value of B_1 + ... + B_N for B_1,...,B_N that satisfy the condition, modulo (10^9 +7).

Sample Input 1

3
2 3 4

Sample Output 1

13

Let B_1=6, B_2=4, and B_3=3, and the condition will be satisfied.

Sample Input 2

5
12 12 12 12 12

Sample Output 2

5

We can let all B_i be 1.

Sample Input 3

3
1000000 999999 999998

Sample Output 3

996989508

Print the sum modulo (10^9+7).

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::convert::From;
use std::ops;

fn read<T: std::str::FromStr>(
    stdin_lock: &mut std::io::StdinLock,
    buf: &mut Vec<u8>,
    delimiter: u8,
) -> T {
    buf.clear();
    let l = std::io::BufRead::read_until(stdin_lock, delimiter, buf).unwrap();
    buf.truncate(l - 1); // remove delimiter
    let s = unsafe { std::str::from_utf8_unchecked(&buf) };
    s.parse().unwrap_or_else(|_| panic!("read"))
}

const MODP: u64 = 1_000_000_007;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
struct ModU64(u64);

impl ModU64 {
    fn new(x: u64) -> Self {
        ModU64(x % MODP)
    }

    fn pow(self, mut x: u64) -> Self {
        let mut b = self;
        let mut a: ModU64 = 1.into();
        while x > 1 {
            if x & 1 == 1 {
                a = a * b;
            }
            x = x / 2;
            b = b * b;
        }
        if x == 1 {
            a = a * b;
        }
        a
    }
}

impl From<u64> for ModU64 {
    fn from(x: u64) -> Self {
        ModU64::new(x)
    }
}

impl ops::Add<ModU64> for ModU64 {
    type Output = ModU64;

    fn add(self, rhs: ModU64) -> Self::Output {
        ModU64::new(self.0 + rhs.0)
    }
}

impl ops::Mul<ModU64> for ModU64 {
    type Output = ModU64;

    fn mul(self, rhs: ModU64) -> Self::Output {
        ModU64::new(self.0 * rhs.0)
    }
}

impl ops::Div<ModU64> for ModU64 {
    type Output = ModU64;

    fn div(self, rhs: ModU64) -> Self::Output {
        self * rhs.pow(MODP - 2)
    }
}

fn main() {
    use std::cmp::max;
    use std::collections::HashMap;

    let stdin = std::io::stdin();
    let mut stdin_lock = stdin.lock();
    let mut buf: Vec<u8> = Vec::new();
    let n: usize = read(&mut stdin_lock, &mut buf, b'\n');
    let mut av = vec![0u64; n];
    for i in 0..n - 1 {
        av[i] = read(&mut stdin_lock, &mut buf, b' ');
    }
    av[n - 1] = read(&mut stdin_lock, &mut buf, b'\n');

    let mut sieve: Vec<u64> = (0..1_000_000 + 1).map(|i| i as u64).collect();
    for ri in 2..sieve.len() {
        let i = sieve.len() - ri + 1;
        // for j in ((i + 1)..sieve.len()).step_by(i) { ... }
        let mut j = i + i;
        while j < sieve.len() {
            sieve[j] = i as u64;
            j += i;
        }
    }

    assert_eq!(sieve[0..10], [0, 1, 2, 3, 2, 5, 2, 7, 2, 3]);

    let mut apv: Vec<HashMap<u64, u64>> = vec![HashMap::new(); n];
    for i in 0..av.len() {
        let mut j = av[i];
        while j != 1 {
            let p = sieve[j as usize];
            *apv[i].entry(p).or_insert(0) += 1;
            j /= p;
        }
    }

    let mut l: HashMap<u64, u64> = HashMap::new();
    for a in apv.iter() {
        for (k, v) in a.iter() {
            if let Some(lv) = l.get_mut(k) {
                *lv = max(*lv, *v);
                continue;
            }
            l.insert(*k, *v);
        }
    }

    let mut lcm: ModU64 = 1.into();
    for (&k, &v) in l.iter() {
        for _ in 0..v {
            lcm = lcm * (k as u64).into();
        }
    }

    let mut ans: ModU64 = 0.into();
    for &a in av.iter() {
        let b = lcm / a.into();
        ans = ans + b;
    }
    println!("{}", ans.0);
}