public void Solve_1() { var crt1 = new CRT(3, 5); var crt2 = new CRT(15, 7); var x1 = crt1.Solve(2, 3); var x2 = crt2.Solve(x1, 2); Assert.AreEqual(23, x2); }
public void Solve_2() { var expected = 1_000000000_000000000; var p1 = 998244353; var p2 = 1107296257; var crt = new CRT(p1, p2); var actual = crt.Solve(expected % p1, expected % p2); Assert.AreEqual(expected, actual); }
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 Convolution() { const long p1 = 998244353, g1 = 3; const long p2 = 1107296257, g2 = 10; var fntt1 = new FNTT202(8, p1, g1); var fntt2 = new FNTT202(8, p2, g2); var a = new long[] { 1000000, 1000000, 1000000 }; var b = new long[] { 1000000, 1000000, 1000000, 1000000 }; var c1 = fntt1.Convolution(a, b); var c2 = fntt2.Convolution(a, b); var crt = new CRT(p1, p2); var c = c1.Zip(c2, (x, y) => crt.Solve(x, y)).ToArray(); var expected = new long[] { 1000000000000, 2000000000000, 3000000000000, 3000000000000, 2000000000000, 1000000000000, 0, 0 }; CollectionAssert.AreEqual(expected, c); }