public void Ntt_Fft_Many() { var n = 1 << 16; var a = Enumerable.Range(3, n).Select(x => (long)x).ToArray(); var ntt = new Ntt(n); var t = ntt.Fft(a); var r = ntt.Fft(t, true); CollectionAssert.AreEqual(a, r); }
// 長さは n 以下で OK。 public static long[] Convolution(long[] a, long[] b) { var ntt = new Ntt(a.Length + b.Length - 1); var fa = ntt.Fft(a); var fb = ntt.Fft(b); for (int i = 0; i < ntt.n; ++i) { fa[i] = fa[i] * fb[i] % p; } return(ntt.Fft(fa, true)); }
public void Ntt_Fft() { var n = 1 << 4; var a = Enumerable.Range(3, n).Select(x => (long)x).ToArray(); var t0 = Ntt0.Naive(a); var r0 = Ntt0.Naive(t0, true); var t1 = Ntt0.Fft(a); var r1 = Ntt0.Fft(t1, true); var ntt = new Ntt(n); var t2 = ntt.Fft(a); var r2 = ntt.Fft(t2, true); CollectionAssert.AreEqual(t0, t1); CollectionAssert.AreEqual(t0, t2); CollectionAssert.AreEqual(a, r0); CollectionAssert.AreEqual(a, r1); CollectionAssert.AreEqual(a, r2); }