Problem:
Score : 300 points

Problem Statement

Given are N integers A_1,\ldots,A_N.

Find the sum of A_i \times A_j over all pairs (i,j) such that 1\leq i < j \leq N, modulo (10^9+7).

Constraints

2 \leq N \leq 2\times 10^5

0 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 \ldots A_N

Output

Print \sum_{i=1}^{N-1}\sum_{j=i+1}^{N} A_i A_j, modulo (10^9+7).

Sample Input 1

3
1 2 3

Sample Output 1

11

We have 1 \times 2 + 1 \times 3 + 2 \times 3 = 11.

Sample Input 2

4
141421356 17320508 22360679 244949

Sample Output 2

437235829

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

use modint::ModInt;
use proconio::{fastout, input};

// \sum_i \sum_j A_iA_j = \sum_{i=1}^{n-1} A_i \sum_{j=i+1}^n A_j

#[fastout]
fn main() {
    input! {
        n: usize,
        a: [i64; n],
    }

    let mut s = vec![ModInt::from(0)];
    for ai in a.iter().copied() {
        let last = s.last().copied().unwrap();
        s.push(last + ai.into());
    }
    let mut ans = ModInt::from(0);
    for i in 0..(n - 1) {
        ans += ModInt::from(a[i]) * (s[n] - s[i + 1].into());
    }
    println!("{}", ans.0);
}

mod modint {
    use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};

    pub const MODULO: u64 = 1_000_000_007;
    // pub const MODULO: u64 = 11;

    fn positive_rem(a: i64, b: u64) -> u64 {
        let b = b as i64;
        let mut value = a % b;
        if value < 0 {
            value += b;
        }
        value as u64
    }

    /// Return (x, y) s.t. ax + by = d where d = gcd(a, b)
    #[allow(unused)]
    pub fn ext_gcd(a: u64, b: u64) -> (i64, i64) {
        if b == 0 {
            return (1, 0);
        }

        let q = (a / b) as i64;
        let r = a % b;
        let (x1, y1) = ext_gcd(b, r);
        (y1, x1 - q * y1)
    }

    #[derive(Debug, Copy, Clone)]
    pub struct ModInt(pub u64);

    impl From<usize> for ModInt {
        fn from(n: usize) -> ModInt {
            ModInt(n as u64 % MODULO)
        }
    }

    impl From<isize> for ModInt {
        fn from(n: isize) -> ModInt {
            ModInt(positive_rem(n as i64, MODULO as u64))
        }
    }

    impl From<u64> for ModInt {
        fn from(n: u64) -> ModInt {
            ModInt(positive_rem(n as i64, MODULO as u64))
        }
    }

    impl From<i64> for ModInt {
        fn from(n: i64) -> ModInt {
            ModInt(positive_rem(n, MODULO as u64))
        }
    }

    impl From<i32> for ModInt {
        fn from(n: i32) -> ModInt {
            ModInt(positive_rem(n as i64, MODULO as u64))
        }
    }

    impl ModInt {
        #[allow(unused)]
        pub fn pow(self, p: u64) -> ModInt {
            if self == ModInt::from(0) {
                return ModInt::from(0);
            }
            if p == 0 {
                return ModInt::from(1);
            }

            if p % 2 == 0 {
                let half = self.pow(p / 2);
                half * half
            } else {
                self.pow(p - 1) * self
            }
        }

        // when MODULO is prime
        #[allow(unused)]
        pub fn inv(self) -> ModInt {
            let (x, _) = ext_gcd(self.0 as u64, MODULO as u64);
            ModInt::from(x)
        }
    }

    impl Add for ModInt {
        type Output = ModInt;

        fn add(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 + other.0)
        }
    }

    impl Sub for ModInt {
        type Output = ModInt;

        fn sub(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 as i64 - other.0 as i64)
        }
    }

    impl Mul for ModInt {
        type Output = ModInt;

        fn mul(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 * other.0)
        }
    }

    impl Neg for ModInt {
        type Output = ModInt;

        fn neg(self) -> Self::Output {
            ModInt::from(0) - self
        }
    }

    impl AddAssign for ModInt {
        fn add_assign(&mut self, other: Self) {
            *self = *self + other;
        }
    }

    impl MulAssign for ModInt {
        fn mul_assign(&mut self, other: Self) {
            *self = *self * other;
        }
    }

    impl SubAssign for ModInt {
        fn sub_assign(&mut self, other: Self) {
            *self = *self - other;
        }
    }

    impl PartialEq for ModInt {
        fn eq(&self, &other: &Self) -> bool {
            self.0 == other.0
        }
    }

    impl Eq for ModInt {}

    #[derive(Debug)]
    pub struct ModIntUtil {
        factorial: Vec<ModInt>,
        factorial_inv: Vec<ModInt>,
        inv: Vec<ModInt>,
    }

    impl ModIntUtil {
        #[allow(unused)]
        pub fn new() -> ModIntUtil {
            ModIntUtil {
                factorial: vec![ModInt::from(1), ModInt::from(1)],
                factorial_inv: vec![ModInt::from(1), ModInt::from(1)],
                inv: vec![ModInt::from(0), ModInt::from(1)],
            }
        }

        fn calc_cache(&mut self, n: usize) {
            let len = self.factorial.len();
            if len < n + 1 {
                for i in len..(n + 1) {
                    let prev = *self.factorial.last().unwrap();
                    self.factorial.push(prev * ModInt::from(i));

                    let inv_i = -self.inv[MODULO as usize % i] * ModInt::from(MODULO as usize / i);
                    self.inv.push(inv_i);

                    let prev = *self.factorial_inv.last().unwrap();
                    self.factorial_inv.push(prev * self.inv[i]);
                }
            }
        }

        #[allow(unused)]
        pub fn factorial(&mut self, n: usize) -> ModInt {
            self.calc_cache(n);
            self.factorial[n]
        }

        #[allow(unused)]
        pub fn factorial_inv(&mut self, n: usize) -> ModInt {
            self.calc_cache(n);
            self.factorial_inv[n]
        }

        // when MODULO is prime
        #[allow(unused)]
        pub fn binom_coef(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }

            self.calc_cache(n);
            self.factorial[n] * self.factorial_inv[k] * self.factorial_inv[n - k]
        }

        #[allow(unused)]
        fn perm(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }
            self.factorial(n) * self.factorial_inv(n - k)
        }

        // Not tested!!
        #[allow(unused)]
        pub fn multi_coef(&mut self, v: &[usize]) -> ModInt {
            let n = v.iter().sum();
            self.calc_cache(n);

            let mut ret = ModInt::from(1);
            ret *= self.factorial[n];
            for v_i in v {
                ret *= self.factorial_inv[*v_i];
            }

            ret
        }
    }
}