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++ (Clang 10.0.0) (judge verdict: Time Limit Exceeded)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<queue>
#include<stack>
#include<complex>
using namespace std;
#define MOD 1000000007
#define MOD2 998244353
#define INF (1<<29)
#define LINF (1LL<<60)
#define EPS (1e-10)
#define PI 3.1415926535897932384626433832795028
typedef long long Int;
//typedef pair<Int, Int> P;
typedef long double Real;
typedef complex<Real> CP;

Int P = 200003;
Int order[200004];
Int cnt[200004];
Int cntr[200004];
Int sum, sqsum;
Int n, a;

vector<CP> INV_FFT(vector<CP>&);
vector<CP> FFT2POW(vector<CP> &x, CP w){
    if(x.size() == 1)return x;
    Int n = x.size();
    vector<CP> even;
    vector<CP> odd;
    for(Int i = 0;i < n;i++){
        if(i % 2 == 0)even.push_back(x[i]);
        else odd.push_back(x[i]);
    }
    even = FFT2POW(even, w * w);
    odd = FFT2POW(odd, w * w);
    vector<CP> res(n);
    CP w_i = 1;
    for(Int i = 0;i < n;i++){
        res[i] = even[i % even.size()] + w_i * odd[i % odd.size()];
        w_i *= w;
    }
    return res;
}

CP primitive_root(Int n){
    double theta = 2 * PI/ n;
    return CP(cos(theta), sin(theta));
}

vector<CP> FFT(vector<CP> &a){
    Int n = a.size();
    if((n & -n) == n)return FFT2POW(a, primitive_root(n));
    
    Int m = 1;
    while(m < 2*n)m <<= 1;
    
    CP w = primitive_root(2 * n);
    vector<CP> ws(2*n+1,1);
    for(Int i = 1;i <= 2*n;i++)ws[i] = ws[i-1] * w;

    vector<CP> winv(m, 0);
    vector<CP> aw(m, 0);
    for(Int i = 0;i < n;i++){
        Int p = -(i*i) % (2*n) + 2*n;
        winv[n-i] = winv[n+i] = ws[p];
        aw[i] = a[i] * ws[i*i%(2*n)];
    }
    auto AW = FFT(aw);
    auto WINV = FFT(winv);
    for(int i = 0;i < m;i++)WINV[i] *= AW[i];
    vector<CP> c = INV_FFT(WINV);
    vector<CP> A(n);
    for(Int i = 0;i < n;i++){
        A[i] = ws[i*i%(2*n)] * c[n+i]; 
    }
    return A;    
}

vector<CP> INV_FFT(vector<CP>& x){
    reverse(x.begin() + 1, x.end());
    auto res = FFT(x);
    for(auto &elem:res)elem /= res.size();
    return res;
}



int main(){
    Int now = 1;
    bool ok = true;
    Int extra = 0;
    for(Int i = 0;i < P-1;i++){
        order[now] = i;
        now = now * 2 % P;
    }
    vector<CP> cnt(200002, 0);
    cin >> n;
    for(int i = 0;i < n;i++){
        cin >> a;
        extra += a * a % P;
        if(a == 0)continue;
        cnt[order[a]] += 1;
    }
    auto CNT = FFT(cnt);
    for(auto &elem:CNT)elem *= elem;
    auto result = INV_FFT(CNT);
    Int ans = 0;
    now = 1;
    for(Int i = 0;i < P-1;i++){
        Int r = Int(result[i].real() + 0.5);
        ans += now * r;
        now = now * 2 % P;
    }
ans -= extra;    
    cout << ans / 2<< endl;
    return 0;
}