예제 #1
0
        public void Solve_1()
        {
            var crt1 = new CRT(3, 5);
            var crt2 = new CRT(15, 7);

            var x1 = crt1.Solve(2, 3);
            var x2 = crt2.Solve(x1, 2);

            Assert.AreEqual(23, x2);
        }
예제 #2
0
        public void Solve_2()
        {
            var expected = 1_000000000_000000000;
            var p1       = 998244353;
            var p2       = 1107296257;

            var crt    = new CRT(p1, p2);
            var actual = crt.Solve(expected % p1, expected % p2);

            Assert.AreEqual(expected, actual);
        }
예제 #3
0
    static void Main()
    {
        var n = int.Parse(Console.ReadLine());
        var a = new long[n + 1];
        var b = new long[n + 1];

        for (int i = 1; i <= n; i++)
        {
            var v = Read();
            a[i] = v[0];
            b[i] = v[1];
        }

        var ab1 = new FNTT302(1 << 20, p1, g1).Convolution(a, b);
        var ab2 = new FNTT302(1 << 20, p2, g2).Convolution(a, b);

        var crt = new CRT(p1, p2);
        var ab  = ab1.Zip(ab2, (x, y) => crt.Solve(x, y)).ToArray();

        Console.WriteLine(string.Join("\n", ab[1..]));
예제 #4
0
    static object Solve()
    {
        var n = int.Parse(Console.ReadLine());
        var a = ReadL();

        // g^{p-1} == 1
        var pg    = new long[p - 1];
        var pgMap = new long[p];

        pg[0] = 1;
        for (int i = 1; i < pg.Length; i++)
        {
            pg[i]        = pg[i - 1] * g % p;
            pgMap[pg[i]] = i;
        }

        var r = 0L;
        var c = new long[p - 1];

        foreach (var x in a)
        {
            if (x == 0)
            {
                continue;
            }
            c[pgMap[x]]++;
            r -= x * x % p;
        }

        var c1 = new FNTT302(1 << 20, p1, g1).Convolution(c, c);
        var c2 = new FNTT302(1 << 20, p2, g2).Convolution(c, c);

        var crt  = new CRT(p1, p2);
        var conv = c1.Zip(c2, (x, y) => crt.Solve(x, y)).ToArray();

        for (int i = 0; i < conv.Length; i++)
        {
            r += conv[i] * pg[i % (p - 1)];
        }
        return(r / 2);
    }
예제 #5
0
        public void Convolution()
        {
            const long p1 = 998244353, g1 = 3;
            const long p2 = 1107296257, g2 = 10;

            var fntt1 = new FNTT202(8, p1, g1);
            var fntt2 = new FNTT202(8, p2, g2);

            var a = new long[] { 1000000, 1000000, 1000000 };
            var b = new long[] { 1000000, 1000000, 1000000, 1000000 };

            var c1 = fntt1.Convolution(a, b);
            var c2 = fntt2.Convolution(a, b);

            var crt = new CRT(p1, p2);
            var c   = c1.Zip(c2, (x, y) => crt.Solve(x, y)).ToArray();

            var expected = new long[] { 1000000000000, 2000000000000, 3000000000000, 3000000000000, 2000000000000, 1000000000000, 0, 0 };

            CollectionAssert.AreEqual(expected, c);
        }