コード例 #1
0
        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);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        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);
        }
コード例 #4
0
    // 長さは 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));
    }
コード例 #5
0
    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));
        }
    }
コード例 #6
0
        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);
        }