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;

typedef long long LL;

const int N=524288,mod=200003;
const double pi=acos(-1);

int add(int a,int b,int p=mod){return a+b>=p?a+b-p:a+b;}
int sub(int a,int b,int p=mod){return a-b<0?a-b+p:a-b;}
int mul(int a,int b,int p=mod){return (LL)a*b%p;}
void sadd(int &a,int b,int p=mod){a=add(a,b,p);}
void ssub(int &a,int b,int p=mod){a=sub(a,b,p);}
void smul(int &a,int b,int p=mod){a=mul(a,b,p);}

struct comp{
  double x,y;
  comp(double X=0,double Y=0){x=X;y=Y;}
  comp operator + (const comp &p)const{return comp(x+p.x,y+p.y);}
  comp operator - (const comp &p)const{return comp(x-p.x,y-p.y);}
  comp operator * (const comp &p)const{return comp(x*p.x-y*p.y,x*p.y+y*p.x);}
  comp operator * (const double &p)const{return comp(x*p,y*p);}
  comp operator / (const double &p)const{return comp(x/p,y/p);}
};

comp wn[2][N+9];

void Get_wn(){
  for (int i=0;i<N;++i){
	wn[0][i]=comp(cos(2*i*pi/N),sin(2*i*pi/N));
	wn[1][i]=comp(cos(2*i*pi/N),-sin(2*i*pi/N));
  }
}

int len,rev[N+9];

void Get_len(int n){
  int l=0;
  for (len=1;len<=n;len<<=1) ++l;
  for (int i=0;i<len;++i) rev[i]=rev[i>>1]>>1|(i&1)<<l-1;
}

comp pw[N+9];

void FFT(comp *a,int n,int t){
  for (int i=0;i<n;++i)
	if (i<rev[i]) swap(a[i],a[rev[i]]);
  for (int i=1;i<n;i<<=1){
	int tl=N/(i<<1);
	for (int j=0;j<i;++j) pw[j]=wn[t][j*tl];
	for (int j=0;j<n;j+=i<<1)
	  for (int k=0;k<i;++k){
		comp x=a[j+k],y=pw[k]*a[i+j+k];
		a[j+k]=x+y;a[i+j+k]=x-y;
	  }
  }
  if (!t) return;
  for (int i=0;i<n;++i) a[i]=a[i]/n;
}

int n,a[N+9];
int pw2[N+9],cnt[N+9];

void Get_pw2(){
  pw2[0]=1;
  for (int i=1;i<mod<<1;++i) pw2[i]=mul(pw2[i-1],2);
  for (int i=0;i<mod-1;++i){
	cnt[i]=a[pw2[i]];
	//if (cnt[i]) printf("%d : %d\n",i,cnt[i]);
  }
}

comp tc[N+9];
LL c[N+9];
LL ans;

void Get_ans(){
  Get_len(mod<<1);
  /*for (int i=0;i<mod;++i)
	if (cnt[i]){
	  for (int j=0;j<mod;++j) c[i+j]+=1LL*cnt[i]*cnt[j];
	}
  //for (int i=0;i<mod<<1;++i) if (c[i]) printf("%d :  %lld\n",i,c[i]);
  */
  for (int i=0;i<mod;++i) tc[i]=comp(1.0*cnt[i],0);
  FFT(tc,len,0);
  for (int i=0;i<len;++i) tc[i]=tc[i]*tc[i];
  FFT(tc,len,1);
  for (int i=0;i<len;++i) c[i]=(LL)(tc[i].x+0.5);
  for (int i=0;i<mod;++i) c[i<<1]-=cnt[i];
  for (int i=0;i<mod<<1;++i){
	c[i]>>=1;
	ans+=c[i]*pw2[i];
  }
}

void work(){
  scanf("%d",&n);
  for (int i=1;i<=n;++i){
	int x;
	scanf("%d",&x);
	if (x) ++a[x];
  }
  Get_wn();
  Get_pw2();
  Get_ans();
  printf("%lld\n",ans);
}

int main(){
  int T=1;
  //scanf("%d",&T);
  for (;T--;) work();
  return 0;
}