static void Main() { var n = int.Parse(Console.ReadLine()); var a = new long[n + 1]; var b = new long[n + 1]; for (int i = 1; i <= n; i++) { var v = Read(); a[i] = v[0]; b[i] = v[1]; } var ab1 = new FNTT302(1 << 20, p1, g1).Convolution(a, b); var ab2 = new FNTT302(1 << 20, p2, g2).Convolution(a, b); var crt = new CRT(p1, p2); var ab = ab1.Zip(ab2, (x, y) => crt.Solve(x, y)).ToArray(); Console.WriteLine(string.Join("\n", ab[1..]));
static object Solve() { var n = int.Parse(Console.ReadLine()); var a = ReadL(); // g^{p-1} == 1 var pg = new long[p - 1]; var pgMap = new long[p]; pg[0] = 1; for (int i = 1; i < pg.Length; i++) { pg[i] = pg[i - 1] * g % p; pgMap[pg[i]] = i; } var r = 0L; var c = new long[p - 1]; foreach (var x in a) { if (x == 0) { continue; } c[pgMap[x]]++; r -= x * x % p; } var c1 = new FNTT302(1 << 20, p1, g1).Convolution(c, c); var c2 = new FNTT302(1 << 20, p2, g2).Convolution(c, c); var crt = new CRT(p1, p2); var conv = c1.Zip(c2, (x, y) => crt.Solve(x, y)).ToArray(); for (int i = 0; i < conv.Length; i++) { r += conv[i] * pg[i % (p - 1)]; } return(r / 2); }
public void Transform_FNTT302() { var ntt = new FNTT302(); Test(f => ntt.Transform(f, false), f => ntt.Transform(f, true)); }
public void Convolution_FNTT302() { var ntt = new FNTT302(); Test(ntt.Convolution); }