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 Lua (LuaJIT 2.1.0) (judge verdict: Accepted)

local mfl = math.floor
local TranFFT = {}

TranFFT.initialize = function(self)
  self.size = 19
  -- 2^19 = 524288
  self.n = 524288
  -- 40003698689: prime,
  -- 40003698689 % 524288 = 1
  self.mod = 40003698689
  -- (463881^524288) % mod = 1
  self.w = 463881
  -- (40003622388 * 524288) % mod = 1
  self.ninv = 40003622388
  -- (1547695164 * 463881) % mod = 1
  self.winv = 1547695164

  self.p2 = {1}
  for i = 2, self.size do
    self.p2[i] = self.p2[i - 1] * 2
  end
  self.binv = {}
  for i = 1, self.n do
    local y, z = 0, i - 1
    for j = 1, self.size do
      y = y + (z % 2) * self.p2[self.size + 1 - j]
      z = mfl(z / 2)
    end
    self.binv[i] = y + 1
  end
  self.wmul = {1}
  local w1 = self.w % 10000
  local w2 = mfl(self.w / 10000) % 10000
  local w3 = mfl(self.w / 100000000)
  for i = 2, self.n do
    self.wmul[i] = self:mul_predef(self.wmul[i - 1], w1, w2, w3)
  end
  self.winvmul = {1}
  w1 = self.winv % 10000
  w2 = mfl(self.winv / 10000) % 10000
  w3 = mfl(self.winv / 100000000)
  for i = 2, self.n do
    self.winvmul[i] = self:mul_predef(self.winvmul[i - 1], w1, w2, w3)
  end
end
TranFFT.add = function(self, x, y) return (x + y) % self.mod end

-- super slow multiply functions
TranFFT.mul = function(self, x, y)
  local mod = self.mod
  local x1, y1 = x % 10000, y % 10000
  local x2, y2 = mfl(x / 10000) % 10000, mfl(y / 10000) % 10000
  local x3, y3 = mfl(x / 100000000), mfl(y / 100000000)
  local ret = (x1 * y1 + (x1 * y2 + x2 * y1) * 10000) % mod
  ret = (ret + (x1 * y3 + x2 * y2 + x3 * y1) * 10000 % mod * 10000 % mod) % mod
  ret = (ret + (x2 * y3 + x3 * y2) * 10000 % mod * 10000 % mod * 10000) % mod
  ret = (ret +  x3 * y3 * 10000 % mod * 10000 % mod * 10000 % mod * 10000) % mod
  return ret
end

TranFFT.mul_predef = function(self, x, y1, y2, y3)
  local mod = self.mod
  local x1 = x % 10000
  local x2 = mfl(x / 10000) % 10000
  local x3 = mfl(x / 100000000)
  local ret = (x1 * y1 + (x1 * y2 + x2 * y1) * 10000) % mod
  ret = (ret + (x1 * y3 + x2 * y2 + x3 * y1) * 10000 % mod * 10000 % mod) % mod
  ret = (ret + (x2 * y3 + x3 * y2) * 10000 % mod * 10000 % mod * 10000) % mod
  ret = (ret +  x3 * y3 * 10000 % mod * 10000 % mod * 10000 % mod * 10000) % mod
  return ret
end

TranFFT.twice = function(self, x)
  local mod = self.mod
  local x1 = x % 10000
  local x2 = mfl(x / 10000) % 10000
  local x3 = mfl(x / 100000000)
  local ret = (x1 * x1 + (2 * x1 * x2) * 10000) % mod
  ret = (ret + (2 * x1 * x3 + x2 * x2) * 10000 % mod * 10000 % mod) % mod
  ret = (ret + (2 * x2 * x3) * 10000 % mod * 10000 % mod * 10000) % mod
  ret = (ret +  x3 * x3 * 10000 % mod * 10000 % mod * 10000 % mod * 10000) % mod
  return ret
end

TranFFT.fft_common = function(self, ary, wmul)
  local ret = {}
  for i = 1, self.n do
    ret[i] = ary[self.binv[i]]
  end
  for i = 1, self.size do
    local step_size = self.p2[i]
    local step_count = self.p2[self.size + 1 - i]
    for istep = 1, step_count do
      local ofst = (istep - 1) * step_size * 2
      for j = 1, step_size do
        local a1, a2 = ret[ofst + j], ret[ofst + step_size + j]
        ret[ofst + j] = self:add(a1, self:mul(a2, wmul[1 + (j - 1) * step_count]))
        ret[ofst + step_size + j] = self:add(a1, self:mul(a2, wmul[1 + (j + step_size - 1) * step_count]))
      end
    end
  end
  return ret
end

TranFFT.fft = function(self, ary)
  return self:fft_common(ary, self.wmul)
end
TranFFT.ifft = function(self, ary)
  local ret = self:fft_common(ary, self.winvmul)
  for i = 1, self.n do
    ret[i] = self:mul(ret[i], self.ninv)
  end
  return ret
end

TranFFT:initialize()
local a = {}
for i = 1, TranFFT.n do
  a[i] = 0
end

local prime = 200003
local function pmul(x, y) return (x * y) % prime end
local function padd(x, y) return (x + y) % prime end

local p2 = {1}
local p2inv = {0}
for i = 2, prime - 1 do
  p2[i] = (p2[i - 1] * 2) % prime
  p2inv[i] = 0
end
for i = 1, prime - 1 do
  p2inv[p2[i]] = i
end

local n = io.read("*n")
local t = {}
for i = 1, n do
  t[i] = io.read("*n")
  if 0 < t[i] then
    local v = p2inv[t[i]]
    a[v] = a[v] + 1
  end
end
local at = TranFFT:fft(a)
for i = 1, TranFFT.n do
  -- at[i] = TranFFT:mul(at[i], at[i])
  at[i] = TranFFT:twice(at[i])
end
local c = TranFFT:ifft(at)

local ret = {}
for i = 1, prime - 1 do
  ret[i] = 0
end
for i = 1, prime * 2 - 2 do
  local ti = i
  if prime <= ti then
    ti = ti - (prime - 1)
  end
  local v = p2[ti]
  ret[v] = ret[v] + c[i]
end
for i = 1, n do
  if 0 < t[i] then
    local v = pmul(t[i], t[i])
    ret[v] = ret[v] - 1
  end
end
local ans = 0LL
for i = 1, prime - 1 do
  ans = ans + i * mfl(ret[i] / 2)
end
ans = tostring(ans):gsub("LL", "")
print(ans)
-- print(os.clock())