예제 #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
    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));
        }
    }