Example #1
0
            private static void Initialize()
            {
                if (_sumE != null && _sumIe != null)
                {
                    return;
                }
                var m = ModuloInteger.Modulo;

                _primitiveRoot = PrimitiveRoot(m);
                _sumE          = new ModuloInteger[30];
                _sumIe         = new ModuloInteger[30];
                var es     = new ModuloInteger[30];
                var ies    = new ModuloInteger[30];
                var count2 = BitScanForward(m - 1);
                var e      = new ModuloInteger(_primitiveRoot).Power((m - 1) >> count2);
                var ie     = e.Inverse();

                for (var i = count2; i >= 2; i--)
                {
                    es[i - 2]  = e;
                    ies[i - 2] = ie;
                    e         *= e;
                    ie        *= ie;
                }
                ModuloInteger now  = 1;
                ModuloInteger inow = 1;

                for (var i = 0; i < count2 - 2; i++)
                {
                    _sumE[i]  = es[i] * now;
                    _sumIe[i] = ies[i] * inow;
                    now      *= ies[i];
                    inow     *= es[i];
                }
            }
Example #2
0
        public static void Solve()
        {
            var       N   = Scanner.Scan <int>();
            const int max = (int)1e5 + 1;
            const int p   = 998244353;

            var G = new ModuloInteger[max];

            G[0] = 1;
            for (var i = 1; i < max; i++)
            {
                G[i] = G[i - 1] * (2 * i - 1);
            }

            var freq = new int[max];

            for (var i = 0; i < 2 * N; i++)
            {
                var H = Scanner.Scan <int>();
                freq[H]++;
            }

            var queue = new Queue <ModuloInteger[]>();

            queue.Enqueue(new ModuloInteger[] { 1 });
            foreach (var n in freq)
            {
                if (n < 2)
                {
                    continue;
                }
                var list = new ModuloInteger[n / 2 + 1];
                for (var i = 0; i * 2 <= n; i++)
                {
                    list[i] = Enumeration.CombinationCount(n, i * 2, p) * G[i];
                    if (i % 2 == 1)
                    {
                        list[i] = -list[i];
                    }
                }
                queue.Enqueue(list);
            }

            while (queue.Count > 1)
            {
                var list1 = queue.Dequeue();
                var list2 = queue.Dequeue();
                queue.Enqueue(Convolution.Execute(list1, list2).ToArray());
            }

            ModuloInteger answer = 0;
            var           last   = queue.Dequeue();

            for (var i = 0; i < last.Length; i++)
            {
                answer += last[i] * G[N - i];
            }

            Console.WriteLine(answer);
        }
Example #3
0
            public static IEnumerable <ModuloInteger> Execute(IEnumerable <ModuloInteger> a, IEnumerable <ModuloInteger> b)
            {
                var(a1, b1) = (a.ToArray(), b.ToArray());
                var(n, m)   = (a1.Length, b1.Length);
                var ret = new ModuloInteger[n + m - 1];

                if (System.Math.Min(n, m) <= 60)
                {
                    for (var i = 0; i < n; i++)
                    {
                        for (var j = 0; j < m; j++)
                        {
                            ret[i + j] += a1[i] * b1[j];
                        }
                    }
                    return(ret);
                }
                var z = 1 << CeilPower2(n + m - 1);

                Array.Resize(ref a1, z);
                Array.Resize(ref b1, z);
                a1 = Butterfly(a1).ToArray();
                b1 = Butterfly(b1).ToArray();
                for (var i = 0; i < a1.Length; i++)
                {
                    a1[i] *= b1[i];
                }
                ret = ButterflyInverse(a1).ToArray();
                Array.Resize(ref ret, n + m - 1);
                return(ret.Select(x => x / z));
            }
Example #4
0
        public static void Solve()
        {
            var(N, K) = Scanner.Scan <int, int>();
            var A   = Scanner.ScanEnumerable <int>().Select(x => (ModuloInteger)x).ToArray();
            var sum = new ModuloInteger[K + 1];

            for (var i = 0; i < N; i++)
            {
                ModuloInteger x = 1;
                for (var j = 0; j <= K; j++)
                {
                    sum[j] += x;
                    x      *= A[i];
                }
            }

            var i2 = ModuloInteger.Inverse(2);

            for (var i = 1; i <= K; i++)
            {
                ModuloInteger answer = 0;
                for (var j = 0; j <= i; j++)
                {
                    answer += EnumerationModulo.Combination(i, j) * (sum[j] * sum[i - j] - sum[i]);
                }
                answer *= i2;
                Console.WriteLine(answer);
            }
        }
        public void DynamicBorderTest()
        {
            const int moduloUpper = int.MaxValue;

            for (var modulo = moduloUpper; modulo >= moduloUpper - 20; modulo--)
            {
                ModuloInteger.Modulo = modulo;
                var values = new List <long>();
                for (var i = 0; i < 10; i++)
                {
                    values.Add(i);
                    values.Add(modulo - i);
                    values.Add(modulo / 2 + i);
                    values.Add(modulo / 2 - i);
                }

                foreach (var a in values)
                {
                    Assert.That(new ModuloInteger(a).Power(3).Value, Is.EqualTo(a * a % modulo * a % modulo));
                    foreach (var b in values)
                    {
                        ModuloInteger l = a;
                        ModuloInteger r = b;
                        Assert.That((l + r).Value, Is.EqualTo((a + b) % modulo));
                        Assert.That((l - r).Value, Is.EqualTo((a - b + modulo) % modulo));
                        Assert.That((l * r).Value, Is.EqualTo(a * b % modulo));
                    }
                }
            }
        }
Example #6
0
        public static void Solve()
        {
            var(N, Q) = Scanner.Scan <int, int>();

            S Operation(S a, S b) => new S(a.X * b.W + b.X, a.W * b.W);

            var idData = new S(0, 1);
            var inv9   = ModuloInteger.Inverse(9);

            S Mapping(int f, S x) => f == 0 ? x : new S((x.W - 1) * inv9 * f, x.W);
            int Composition(int f, int g) => f == 0 ? g : f;

            var idInt = 0;

            var lst = new LazySegmentTree <S, int>(N, Operation, idData, Mapping, Composition, idInt);

            for (var i = 0; i < N; i++)
            {
                lst.Set(i, new S(1, 10));
            }
            for (var i = 0; i < Q; i++)
            {
                var(L, R, D) = Scanner.Scan <int, int, int>();
                lst.Apply(L - 1, R, D);
                Console.WriteLine(lst.QueryToAll().X);
            }
        }
Example #7
0
        public static void Solve()
        {
            var(N, M) = Scanner.Scan <int, int>();
            var S  = Scanner.ScanEnumerable <int>().ToArray();
            var T  = Scanner.ScanEnumerable <int>().ToArray();
            var dp = new ModuloInteger[N + 1][].Select(_ => new ModuloInteger[M + 1]).ToArray();

            for (var i = 0; i <= N; i++)
            {
                dp[i][0] = 1;
            }
            for (var i = 0; i <= M; i++)
            {
                dp[0][i] = 1;
            }
            for (var i = 0; i < N; i++)
            {
                for (var j = 0; j < M; j++)
                {
                    dp[i + 1][j + 1] = dp[i][j + 1] + dp[i + 1][j] - dp[i][j];
                    if (S[i] == T[j])
                    {
                        dp[i + 1][j + 1] += dp[i][j];
                    }
                }
            }

            Console.WriteLine(dp[N][M]);
        }
Example #8
0
        public static void Solve()
        {
            var           N      = Scanner.Scan <int>();
            var           A      = Scanner.ScanEnumerable <long>().ToArray();
            ModuloInteger answer = 0;

            for (var bit = 0; bit < 60; bit++)
            {
                ModuloInteger count = 0;
                foreach (var a in A)
                {
                    if ((a >> bit & 1) == 1)
                    {
                        count++;
                    }
                }
                ModuloInteger mul01 = (N - count) * count;
                for (var i = 0; i < bit; i++)
                {
                    mul01 *= 2;
                }
                answer += mul01;
            }

            Console.WriteLine(answer);
        }
Example #9
0
        public static void Solve()
        {
            var S  = Scanner.Scan <string>();
            var N  = S.Length;
            var dp = new ModuloInteger[N + 1][].Select(_ => new ModuloInteger[13]).ToArray();

            dp[0][0] = 1;
            for (var i = 0; i < N; i++)
            {
                var digit = S[i] == '?' ? -1 : S[i] - '0';
                for (var j = 0; j < 10; j++)
                {
                    if (digit != -1 && digit != j)
                    {
                        continue;
                    }
                    for (var k = 0; k < 13; k++)
                    {
                        dp[i + 1][(k * 10 + j) % 13] += dp[i][k];
                    }
                }
            }

            Console.WriteLine(dp[N][5]);
        }
        public void IncrementTest()
        {
            ModuloInteger.Modulo = 11;
            ModuloInteger a = 8;

            Assert.That((++a).Value, Is.EqualTo(9));
            Assert.That((++a).Value, Is.EqualTo(10));
            Assert.That((++a).Value, Is.EqualTo(0));
            Assert.That((++a).Value, Is.EqualTo(1));
            a = 3;
            Assert.That((--a).Value, Is.EqualTo(2));
            Assert.That((--a).Value, Is.EqualTo(1));
            Assert.That((--a).Value, Is.EqualTo(0));
            Assert.That((--a).Value, Is.EqualTo(10));
            a = 8;
            Assert.That((a++).Value, Is.EqualTo(8));
            Assert.That((a++).Value, Is.EqualTo(9));
            Assert.That((a++).Value, Is.EqualTo(10));
            Assert.That((a++).Value, Is.EqualTo(0));
            Assert.That(a.Value, Is.EqualTo(1));
            a = 3;
            Assert.That((a--).Value, Is.EqualTo(3));
            Assert.That((a--).Value, Is.EqualTo(2));
            Assert.That((a--).Value, Is.EqualTo(1));
            Assert.That((a--).Value, Is.EqualTo(0));
            Assert.That(a.Value, Is.EqualTo(10));
        }
Example #11
0
            private static IEnumerable <ModuloInteger> ButterflyInverse(IEnumerable <ModuloInteger> items)
            {
                var ret = items.ToArray();
                var h   = CeilPower2(ret.Length);

                Initialize();
                for (var ph = h; ph >= 1; ph--)
                {
                    var           w    = 1 << (ph - 1);
                    var           p    = 1 << (h - ph);
                    ModuloInteger inow = 1;
                    for (var s = 0; s < w; s++)
                    {
                        var offset = s << (h - ph + 1);
                        for (var i = 0; i < p; i++)
                        {
                            var l = ret[i + offset];
                            var r = ret[i + offset + p];
                            ret[i + offset]     = l + r;
                            ret[i + offset + p] = (l - r) * inow;
                        }
                        inow *= _sumIe[BitScanForward(~s)];
                    }
                }
                return(ret);
            }
Example #12
0
        public static void Solve()
        {
            var           N      = Scanner.Scan <int>();
            var           A      = Scanner.ScanEnumerable <int>().ToArray();
            var           rgb    = new int[3];
            ModuloInteger answer = 1;

            for (var i = 0; i < N; i++)
            {
                var count = 0L;
                var idx   = -1;
                for (var j = 0; j < 3; j++)
                {
                    if (A[i] != rgb[j])
                    {
                        continue;
                    }
                    count++;
                    idx = j;
                }
                answer *= count;
                if (idx == -1)
                {
                    break;
                }
                rgb[idx]++;
            }
            Console.WriteLine(answer);
        }
Example #13
0
        public void MiddleTest()
        {
            ModuloInteger.Modulo = 998244353;
            var random = new Random(19937);
            var a      = new ModuloInteger[1234].Select(_ => (ModuloInteger)random.Next()).ToArray();
            var b      = new ModuloInteger[2345].Select(_ => (ModuloInteger)random.Next()).ToArray();

            Assert.That(Convolution.Execute(a, b), Is.EqualTo(ConvolutionNaive(a, b)));
        }
Example #14
0
        public void Modulo641Test()
        {
            const int mod = 641;

            ModuloInteger.Modulo = mod;
            var a = new ModuloInteger[64].Select(_ => (ModuloInteger)Utilities.RandomInteger(0, mod - 1)).ToArray();
            var b = new ModuloInteger[65].Select(_ => (ModuloInteger)Utilities.RandomInteger(0, mod - 1)).ToArray();

            Assert.That(Convolution.Execute(a, b), Is.EqualTo(ConvolutionNaive(a, b)));
        }
Example #15
0
        public void SimpleModuloIntegerTest([Values(998244353, 924844033)] int mod,
                                            [Range(1, 20)] int n, [Range(1, 20)] int m)
        {
            var random = new Random(19937);

            ModuloInteger.Modulo = mod;
            var a = new ModuloInteger[n].Select(_ => (ModuloInteger)random.Next()).ToArray();
            var b = new ModuloInteger[m].Select(_ => (ModuloInteger)random.Next()).ToArray();

            Assert.That(Convolution.Execute(a, b), Is.EqualTo(ConvolutionNaive(a, b)));
        }
 public void GetHashCodeTest([Values(11, 12, 998244353, 1000000007, 1000000008)] int modulo)
 {
     ModuloInteger.Modulo = modulo;
     for (var i = 1; i < Math.Min(modulo - 1, 1000); i++)
     {
         var x = new ModuloInteger(i);
         var y = x + modulo;
         Assert.That(x, Is.EqualTo(y));
         Assert.That(x.GetHashCode(), Is.EqualTo(y.GetHashCode()));
     }
 }
 public void Inverse998244353Test()
 {
     ModuloInteger.Modulo = 998244353;
     for (var i = 1; i < 100000; i++)
     {
         var x = ModuloInteger.Inverse(i);
         var y = new ModuloInteger(i).Inverse();
         Assert.That(x.Value, Is.GreaterThanOrEqualTo(0));
         Assert.That(x.Value, Is.LessThanOrEqualTo(998244353 - 1));
         Assert.That(x.Value * i % 998244353, Is.EqualTo(1));
         Assert.That(x, Is.EqualTo(y));
     }
 }
Example #18
0
        public void NullCheckTest()
        {
            ModuloInteger[] a = null;
            var             b = new ModuloInteger[10];

            Assert.Throws <ArgumentNullException>(() => Convolution.Execute(a, b));
            Assert.Throws <ArgumentNullException>(() => Convolution.Execute(b, a));

            long[] c = null;
            var    d = new long[10];

            Assert.Throws <ArgumentNullException>(() => Convolution.Execute(c, d));
            Assert.Throws <ArgumentNullException>(() => Convolution.Execute(d, c));
        }
Example #19
0
        public static void Solve()
        {
            var           N      = Scanner.Scan <int>();
            var           C      = Scanner.ScanEnumerable <int>().OrderByDescending(x => x).Select(x => (ModuloInteger)x).ToArray();
            ModuloInteger answer = 0;

            for (var i = 1; i <= N; i++)
            {
                answer += C[i - 1] * (i + 1);
            }
            answer *= ModuloInteger.Power(4, N - 1);

            Console.WriteLine(answer);
        }
 public void InverseTest([Values(11, 12, 1000000007, 1000000008)] int n)
 {
     ModuloInteger.Modulo = n;
     for (var i = 1; i < Math.Min(n, 100000); i++)
     {
         if (GreatestCommonDivisor(i, n) != 1)
         {
             continue;
         }
         var x = ModuloInteger.Inverse(i);
         var y = new ModuloInteger(i).Inverse();
         Assert.That(x * i % n, Is.EqualTo(1));
         Assert.That(x, Is.EqualTo(y));
     }
 }
Example #21
0
        public static void Solve()
        {
            var L      = Scanner.Scan <string>();
            var answer = new ModuloInteger(0);
            var sum    = new ModuloInteger(1);

            for (var i = 0; i < L.Length; i++)
            {
                if (L[i] == '0')
                {
                    continue;
                }
                answer += sum * ModuloInteger.Power(3, L.Length - i - 1);
                sum    *= 2;
            }
            answer += sum;
            Console.WriteLine(answer);
        }
Example #22
0
            public static ModuloInteger Power(ModuloInteger x, long n)
            {
                if (n < 0)
                {
                    throw new ArgumentException();
                }
                var r = new ModuloInteger(1);

                while (n > 0)
                {
                    if ((n & 1) > 0)
                    {
                        r *= x;
                    }
                    x  *= x;
                    n >>= 1;
                }
                return(r);
            }
Example #23
0
        public static void Solve()
        {
            var(H, W, K) = Scanner.Scan <int, int, int>();
            var dp = new ModuloInteger[H + 1, W];

            dp[0, 0] = 1;
            for (var h = 0; h < H; h++)
            {
                for (var w = 0; w < W; w++)
                {
                    for (var s = 0; s < 1 << (W - 1); s++)
                    {
                        var ok = true;
                        for (var k = 0; k < W - 2; k++)
                        {
                            if ((s >> k & 1) == 1 && (s >> (k + 1) & 1) == 1)
                            {
                                ok = false;
                            }
                        }

                        if (!ok)
                        {
                            continue;
                        }
                        if (w >= 1 && (s >> (w - 1) & 1) == 1)
                        {
                            dp[h + 1, w - 1] += dp[h, w];
                        }
                        else if (w <= W - 2 && (s >> w & 1) == 1)
                        {
                            dp[h + 1, w + 1] += dp[h, w];
                        }
                        else
                        {
                            dp[h + 1, w] += dp[h, w];
                        }
                    }
                }
            }

            Console.WriteLine(dp[H, K - 1]);
        }
Example #24
0
            public static ModuloInteger Power(ModuloInteger value, long n)
            {
                if (n < 0)
                {
                    throw new ArgumentException();
                }
                var ret = new ModuloInteger(1);

                while (n > 0)
                {
                    if ((n & 1) > 0)
                    {
                        ret *= value;
                    }
                    value *= value;
                    n    >>= 1;
                }
                return(ret);
            }
Example #25
0
        private static IEnumerable <ModuloInteger> ConvolutionNaive(ModuloInteger[] a, ModuloInteger[] b)
        {
            var n = a.Length;
            var m = b.Length;

            if (n < 1 || m < 1)
            {
                return(new ModuloInteger[0]);
            }
            var ret = new ModuloInteger[n + m - 1];

            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < m; j++)
                {
                    ret[i + j] += a[i] * b[j];
                }
            }
            return(ret);
        }
        public void Modulo1Test()
        {
            ModuloInteger.Modulo = 1;
            for (var i = 0; i < 100; i++)
            {
                for (var j = 0; j < 100; j++)
                {
                    Assert.That((i * (ModuloInteger)j).Value, Is.Zero);
                }
            }

            ModuloInteger l = 1234;
            ModuloInteger r = 5678;

            Assert.That((l + r).Value, Is.Zero);
            Assert.That((l - r).Value, Is.Zero);
            Assert.That((l * r).Value, Is.Zero);
            Assert.That(l.Power(r.Value).Value, Is.Zero);
            Assert.That(l.Inverse().Value, Is.Zero);
        }
        public void UsageTest()
        {
            ModuloInteger.Modulo = 998244353;
            Assert.That(ModuloInteger.Modulo, Is.EqualTo(998244353));
            Assert.That((new ModuloInteger(1) + new ModuloInteger(2)).Value, Is.EqualTo(3));
            Assert.That((1L + new ModuloInteger(2)).Value, Is.EqualTo(3));
            Assert.That((new ModuloInteger(1) + 2L).Value, Is.EqualTo(3));

            ModuloInteger.Modulo = 1000000007;
            Assert.That(ModuloInteger.Modulo, Is.EqualTo(1000000007));

            ModuloInteger.Modulo = 3;
            Assert.That(ModuloInteger.Modulo, Is.EqualTo(3));
            Assert.That((new ModuloInteger(2) - new ModuloInteger(1)).Value, Is.EqualTo(1));
            Assert.That((2L - new ModuloInteger(1)).Value, Is.EqualTo(1));
            Assert.That((new ModuloInteger(2) - 1L).Value, Is.EqualTo(1));
            Assert.That((new ModuloInteger(1) + new ModuloInteger(2)).Value, Is.EqualTo(0));

            ModuloInteger.Modulo = 11;
            Assert.That(ModuloInteger.Modulo, Is.EqualTo(11));
            Assert.That(new ModuloInteger(4).Value, Is.EqualTo(4));
            Assert.That(new ModuloInteger(-4).Value, Is.EqualTo(7));
            Assert.That((new ModuloInteger(3) * new ModuloInteger(5)).Value, Is.EqualTo(4));
            Assert.That(new ModuloInteger(1) == new ModuloInteger(3), Is.False);
            Assert.That(new ModuloInteger(1) != new ModuloInteger(3), Is.True);
            Assert.That(new ModuloInteger(1) == new ModuloInteger(12), Is.True);
            Assert.That(new ModuloInteger(1) != new ModuloInteger(12), Is.False);

            Assert.That(new ModuloInteger(1).ToString(), Is.EqualTo("1"));
            ModuloInteger a = 1;
            ModuloInteger b = 1;
            const long    c = 1;
            const double  d = 1;

            Assert.That(a.Equals(b), Is.True);
            Assert.That(a.Equals(c), Is.True);
            Assert.That(a.Equals(d), Is.False);
            Assert.Throws <ArgumentException>(() => new ModuloInteger(3).Power(-1));
        }
Example #28
0
        public static void Solve()
        {
            var N    = Scanner.Scan <int>();
            var dict = new Dictionary <int, int>();
            var T    = new int[N];

            for (var i = 0; i < N; i++)
            {
                var t = Scanner.Scan <int>();
                if (!dict.ContainsKey(t))
                {
                    dict[t] = 0;
                }
                dict[t]++;
                T[i] = t;
            }

            Array.Sort(T);
            var sum     = 0L;
            var penalty = 0L;

            for (var i = 0; i < N; i++)
            {
                sum     += penalty + T[i];
                penalty += T[i];
            }
            Console.WriteLine(sum);

            ModuloInteger answer = 1;

            foreach (var x in dict.Values)
            {
                for (var i = 1; i <= x; i++)
                {
                    answer *= i;
                }
            }
            Console.WriteLine(answer);
        }
Example #29
0
        public static void Solve()
        {
            var(N, S) = Scanner.Scan <int, int>();
            var A  = Scanner.ScanEnumerable <int>().Select(x => (ModuloInteger)x).ToArray();
            var dp = new ModuloInteger[N + 1][].Select(x => new ModuloInteger[S + 1]).ToArray();

            dp[0][0] = 1;
            for (var i = 0; i < N; i++)
            {
                for (var j = 0; j <= S; j++)
                {
                    dp[i + 1][j] += dp[i][j] * 2;
                    if (j + A[i] <= S)
                    {
                        dp[i + 1][j + A[i]] += dp[i][j];
                    }
                }
            }

            // Console.WriteLine(string.Join("\n", dp.Select(x => string.Join(" ", x))));

            Console.WriteLine(dp[N][S]);
        }
Example #30
0
        public static void Solve()
        {
            var(N, M) = Scanner.Scan <int, int>();
            var A  = new int[M].Select(_ => Scanner.Scan <int>()).ToArray();
            var dp = new ModuloInteger[N + 1];

            dp[0] = 1;
            var j = 0;

            for (var i = 0; i < N; i++)
            {
                if (j < M && i == A[j])
                {
                    j++; continue;
                }
                dp[i + 1] += dp[i];
                if (i + 2 <= N)
                {
                    dp[i + 2] += dp[i];
                }
            }

            Console.WriteLine(dp[N]);
        }