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 C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#define R register
#define mp make_pair
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define int long long
using namespace std;
const int mod = 998244353, P = 200003, N = (1 << 19) + 100, G = 2, B = 4800;

ll n;
int a[N], qlg[N], rev[N], b[N];

inline void getRev(int lim) {
	static int lst = 0, n = 1;
	if (lst == lim) return;
	n = 1 << lim, lst = lim;
	for (R int i = 1; i < n; ++i)
		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << lim >> 1);
	return;
}

inline int addMod(int a, int b) {
	return (a += b) >= mod ? a - mod : a;
}

inline ll quickpow(ll base, ll pw) {
	ll ret = 1;
	while (pw) {
		if (pw & 1) ret = ret * base % mod;
		base = base * base % mod, pw >>= 1;
	}
	return ret;
}

template <class T>
inline void read(T &x) {
	x = 0;
	char ch = getchar(), w = 0;
	while (!isdigit(ch)) w = (ch == '-'), ch = getchar();
	while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
	x = w ? -x : x;
	return;
}

void ntt(int *a, int lim, int inv) {
	getRev(lim);
	int n = 1 << lim;
	for (R int i = 0; i < n; ++i)
		if (i < rev[i]) swap(a[i], a[rev[i]]);
	for (R int l = 2; l <= n; l <<= 1) {
		int m = l >> 1, g = quickpow(3, (mod - 1) / l), d;
		if (inv) g = quickpow(g, mod - 2);
		for (R int i = 0; i < n; i += l)
			for (R int j = i, w = 1; j < i + m; ++j, w = (ll) w * g % mod)
				d = (ll) a[j + m] * w % mod, a[j + m] = addMod(a[j], mod - d), a[j] = addMod(a[j], d);
	}
	if (inv) {
		inv = quickpow(n, mod - 2);
		for (R int i = 0; i < n; ++i)
			a[i] = (ll) a[i] * inv % mod;
	}
	return;
}

signed main() {
	int pw = 2, x, lim = 0;
	for (R int i = 1; i < P - 1; ++i, pw = pw * G % P)
		qlg[pw] = i;
	read(n);
	ll ans = 0, m = 0;
	for (R int i = 1; i <= n; ++i) {
		read(x);
		if (x) ++a[qlg[x]], ++b[x];
		else ++m;
		ans -= (ll) x * x % P;
		while (1 << lim <= (qlg[x] + 10) << 1) ++lim;
	}
	n -= m;
	for (R int i = 1; i < P; ++i) {
		if (b[i] > B) {
			for (R int j = 1; j < P; ++j)
				ans += (ll) i * j % P * b[i] * b[j] * (1 + (i != j));
			n -= b[i], b[i] = a[qlg[i]] = 0;
		}
	}
	ntt(a, lim, 0);
	for (R int i = 0; i < 1 << lim; ++i)
		a[i] = (ll) a[i] * a[i] % mod;
	ntt(a, lim, 1), pw = 1;
	n = n * n;
	for (R int i = 0; i < 1 << lim; ++i)
		ans += (ll) a[i] * pw, pw = pw * G % P, n -= a[i];
	assert(!n);
	cout << ans / 2 << endl;
	return 0;
}