private static ulong[] Convolve <TMod>(ReadOnlySpan <long> a, ReadOnlySpan <long> b) where TMod : struct, IFftMod { int z = 1 << CeilPow2(a.Length + b.Length - 1); var aTemp = new FftModInt <TMod> [z]; for (int i = 0; i < a.Length; i++) { aTemp[i] = new FftModInt <TMod>(a[i]); } var bTemp = new FftModInt <TMod> [z]; for (int i = 0; i < b.Length; i++) { bTemp[i] = new FftModInt <TMod>(b[i]); } var c = Convolve <TMod>(aTemp, bTemp, a.Length, b.Length, z); var result = new ulong[c.Length]; for (int i = 0; i < result.Length; i++) { result[i] = (ulong)c[i].Value; } return(result); }
private static Span <FftModInt <TMod> > Convolve <TMod>(Span <FftModInt <TMod> > a, Span <FftModInt <TMod> > b, int n, int m, int z) where TMod : struct, IFftMod { FftModInt <TMod> .Butterfly(a); FftModInt <TMod> .Butterfly(b); for (int i = 0; i < a.Length; i++) { a[i] *= b[i]; } FftModInt <TMod> .ButterflyInv(a); var result = a[0..(n + m - 1)];