public void Ntt_Convolution_Many() { var a = Enumerable.Range(3, 1 << 16).Select(x => (long)x).ToArray(); var b = Enumerable.Range(7, 1 << 16).Select(x => (long)x).ToArray(); Ntt.Convolution(a, b); }
public void Convolution() { var a = new long[] { 1, 2, 3, 4 }; var b = new long[] { 5, 6, 7, 8, 9 }; var expected = new long[] { 5, 16, 34, 60, 70, 70, 59, 36 }; CollectionAssert.AreEqual(expected, Dft.Convolution(a, b)); CollectionAssert.AreEqual(expected, Dft0.Convolution(a, b)); CollectionAssert.AreEqual(expected, Ntt.Convolution(a, b)); CollectionAssert.AreEqual(expected, Ntt0.Convolution(a, b)); }
static void Main() { var(n, k) = Read2(); var a = ReadL(); var p2 = new long[k + 1]; var f = new long[k + 1]; var f_ = new long[k + 1]; p2[0] = f[0] = f_[0] = 1; for (int x = 1; x <= k; x++) { p2[x] = p2[x - 1] * 2 % M; f[x] = f[x - 1] * x % M; f_[x] = f_[x - 1] * MInv(x) % M; } var pa = Array.ConvertAll(a, _ => 1L); var s1 = new long[k + 1]; var s2 = new long[k + 1]; s1[0] = n; for (int x = 1; x <= k; x++) { var sum = 0L; for (int i = 0; i < n; i++) { sum += pa[i] = pa[i] * a[i] % M; } sum %= M; s1[x] = sum * f_[x] % M; s2[x] = sum * p2[x] % M; } var conv = Ntt.Convolution(s1, s1); var half = MInv(2); for (int x = 1; x <= k; x++) { Console.WriteLine(MInt((f[x] * conv[x] % M - s2[x]) * half)); } }