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>
using namespace std;
 
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse4")
 
#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
 
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(), a.end()
 
typedef long long LL;
typedef pair<int, int> PII;

const double PI = acos(-1.0);
const int MAX = 1 << 18;
const int p = 200003;
const int LEN = MAX << 1;

int mult(int a, int b)
{
	return (LL)a * b % p;
}

typedef complex<double> BASE;

BASE pw[LEN];

void fft(vector<BASE>& a, bool invert)
{
	int lg = 0;
	while((1 << lg) < SZ(a))
		lg++;
	FOR(i, 0, SZ(a))
	{
		int x = 0;
		FOR(j, 0, lg)
			x |= ((i >> j) & 1) << (lg - j - 1);
		if(x < i)
			swap(a[i], a[x]);
	}
	for(int len = 2; len <= SZ(a); len <<= 1)
	{
		int diff = LEN / len;
		if(invert)
			diff = LEN - diff;
		for(int i = 0; i < SZ(a); i += len)
		{
			int pos = 0;
			FOR(j, 0, len >> 1)
			{
				BASE u = a[i + j], v = a[i + j + (len >> 1)] * pw[pos];
				a[i + j] = u + v;
				a[i + j + (len >> 1)] = u - v;
				pos += diff;
				if(pos >= LEN)
					pos -= LEN;
			}
		}
	}
	if(invert)
		FOR(i, 0, SZ(a))
			a[i] /= SZ(a);
}

void initFFT()
{
	double angle = 2 * PI / LEN;
	FOR(i, 0, LEN)
	{
		double ca = i * angle;
		pw[i] = BASE(cos(ca), sin(ca));
	}
}

vector<LL> sqr(vector<int> a)
{
	vector<BASE> A(ALL(a));
	int lg = 0;
	while((1 << lg) < 2 * SZ(a) - 1)
		lg++;
	A.resize(1 << lg);
	fft(A, false);
	FOR(i, 0, SZ(A))
		A[i] *= A[i];
	fft(A, true);
	vector<LL> res(SZ(A));
	FOR(i, 0, SZ(A))
		res[i] = (LL)(A[i].real() + 0.5);
	return res;
}

int a[MAX];
int pw2[MAX], inv[MAX];
LL ans[MAX];

int main()
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	pw2[0] = 1;
	inv[1] = 0;
	FOR(i, 1, p - 1)
	{
		pw2[i] = mult(pw2[i - 1], 2);
		inv[pw2[i]] = i;
	}
	int n;
	cin >> n;
	vector<int> b(p - 1, 0);
	FOR(i, 0, n)
	{
		cin >> a[i];
		if(a[i])
		{
			b[inv[a[i]]]++;
		}
	}
	initFFT();
	auto c = sqr(b);
	while(SZ(c) > p - 1)
	{
		c[SZ(c) - p] += c.back();
		c.pop_back();
	}
	FOR(i, 0, p - 1)
	{
		ans[pw2[i]] = c[i];
	}
	FOR(i, 0, n)
		ans[mult(a[i], a[i])]--;
	LL sum = 0;
	FOR(i, 1, p)
	{
		assert(ans[i] % 2 == 0);
		sum += (ans[i] / 2) * i;
	}
	cout << sum << "\n";
	return 0;
}