Problem:
Score : 800 points

Problem Statement

Let’s take a prime P = 200\,003.
You are given N integers A_1, A_2, \ldots, A_N.
Find the sum of ((A_i \cdot A_j) \bmod P) over all N \cdot (N-1) / 2 unordered pairs of elements (i < j).

Please note that the sum isn't computed modulo P.

Constraints

2 \leq N \leq 200\,000

0 \leq A_i < P = 200\,003

All values in input are integers.

Input

Input is given from Standard Input in the following format.

N
A_1 A_2 \cdots A_N

Output

Print one integer — the sum over ((A_i \cdot A_j) \bmod P).

Sample Input 1

4
2019 0 2020 200002

Sample Output 1

474287

The non-zero products are:

2019 \cdot 2020 \bmod P = 78320

2019 \cdot 200002 \bmod P = 197984

2020 \cdot 200002 \bmod P = 197983

So the answer is 0 + 78320 + 197984 + 0 + 0 + 197983 = 474287.

Sample Input 2

5
1 1 2 2 100000

Sample Output 2

600013

Solution in Rust (1.42.0) (judge verdict: Time Limit Exceeded)

use proconio::input;

const MOD: u64 = 200_003;

fn main() {
    input!(n: usize, a: [u64; n]);
    let a = a.iter().copied().filter(|&x| x != 0).collect::<Vec<_>>();
    let n = a.len();

    let mut table = vec![0; MOD as usize + 1];
    for &x in &a {
        table[x as usize + 1] += 1;
    }
    for i in 0..MOD as usize {
        table[i + 1] += table[i];
    }

    let mut sum_of_quotients = 0;
    for x in 0..MOD {
        let weight = table[x as usize + 1] - table[x as usize];
        if weight == 0 {
            continue;
        }
        let mut now = 0;
        for q in 0..MOD {
            let l = ((q * MOD + x - 1) / x) as usize;
            if MOD as usize <= l {
                break;
            }
            let r = (((q + 1) * MOD + x - 1) / x).min(MOD) as usize;
            now += (table[r] - table[l]) * q;
        }
        sum_of_quotients += weight * now;
    }
    let sum = a.iter().sum::<u64>().pow(2);
    let sum_of_residues = sum - sum_of_quotients * MOD;

    let mut ans = sum_of_residues;
    for &x in &a {
        ans -= (x * x) % MOD;
    }
    assert_eq!(ans % 2, 0);
    ans /= 2;
    println!("{}", ans);
}