Beispiel #1
0
        private static StaticModInt <T>[] CalcurateSumE()
        {
            int g    = InternalMath.PrimitiveRoot((int)default(T).Mod);
            int cnt2 = InternalBit.BSF(default(T).Mod - 1);
            var e    = new StaticModInt <T>(g).Pow((default(T).Mod - 1) >> cnt2);
            var ie   = e.Inv();

            var sumE = new StaticModInt <T> [cnt2 - 2];

            // es[i]^(2^(2+i)) == 1
            Span <StaticModInt <T> > es  = stackalloc StaticModInt <T> [cnt2 - 1];
            Span <StaticModInt <T> > ies = stackalloc StaticModInt <T> [cnt2 - 1];

            for (int i = es.Length - 1; i >= 0; i--)
            {
                // e^(2^(2+i)) == 1
                es[i]  = e;
                ies[i] = ie;
                e     *= e;
                ie    *= ie;
            }

            var now = StaticModInt <T> .Raw(1);

            for (int i = 0; i < sumE.Length; i++)
            {
                sumE[i] = es[i] * now;
                now    *= ies[i];
            }

            return(sumE);
        }
Beispiel #2
0
        public static void Calculate(Span <StaticModInt <T> > a)
        {
            var n = a.Length;
            var h = InternalMath.CeilPow2(n);

            for (int ph = 1; ph <= h; ph++)
            {
                // ブロックサイズの半分
                int w = 1 << (ph - 1);

                // ブロック数
                int p = 1 << (h - ph);

                var now = StaticModInt <T> .Raw(1);

                // 各ブロックの s 段目
                for (int s = 0; s < w; s++)
                {
                    int offset = s << (h - ph + 1);

                    for (int i = 0; i < p; i++)
                    {
                        var l = a[i + offset];
                        var r = a[i + offset + p] * now;
                        a[i + offset]     = l + r;
                        a[i + offset + p] = l - r;
                    }
                    now *= sumE[InternalBit.BSF(~(uint)s)];
                }
            }
        }
Beispiel #3
0
        public static void CalculateInv(Span <StaticModInt <T> > a)
        {
            var n = a.Length;
            var h = InternalMath.CeilPow2(n);

            for (int ph = h; ph >= 1; ph--)
            {
                // ブロックサイズの半分
                int w = 1 << (ph - 1);

                // ブロック数
                int p = 1 << (h - ph);

                var iNow = StaticModInt <T> .Raw(1);

                // 各ブロックの s 段目
                for (int s = 0; s < w; s++)
                {
                    int offset = s << (h - ph + 1);

                    for (int i = 0; i < p; i++)
                    {
                        var l = a[i + offset];
                        var r = a[i + offset + p];
                        a[i + offset]     = l + r;
                        a[i + offset + p] = StaticModInt <T> .Raw(
                            unchecked ((int)((ulong)(default(T).Mod + l.Value - r.Value) * (ulong)iNow.Value % default(T).Mod)));
                    }
                    iNow *= sumIE[InternalBit.BSF(~(uint)s)];
                }
            }
        }
        public void SafeMod()
        {
            var preds = new List <long>();

            for (int i = 0; i <= 100; i++)
            {
                preds.Add(i);
                preds.Add(-i);
                preds.Add(i);
                preds.Add(long.MinValue + i);
                preds.Add(long.MaxValue - i);
            }

            foreach (var a in preds)
            {
                foreach (var b in preds)
                {
                    if (b <= 0)
                    {
                        continue;
                    }
                    var ans = (long)((new BigInteger(a) % b + b) % b);
                    InternalMath.SafeMod(a, b).Should().Be(ans);
                }
            }
        }
 public void PrimitiveRootTest()
 {
     for (int i = 0; i < 1000; i++)
     {
         int x = int.MaxValue - i;
         if (!InternalMath.IsPrime(x))
         {
             continue;
         }
         MathUtil.IsPrimitiveRoot(x, mods[x].PrimitiveRoot()).Should().BeTrue();
     }
 }
 public void PrimitiveRootTemplateTest()
 {
     MathUtil.IsPrimitiveRoot(2, InternalMath.PrimitiveRoot <Mod2>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(3, InternalMath.PrimitiveRoot <Mod3>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(5, InternalMath.PrimitiveRoot <Mod5>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(7, InternalMath.PrimitiveRoot <Mod7>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(11, InternalMath.PrimitiveRoot <Mod11>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(998244353, InternalMath.PrimitiveRoot <Mod998244353>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(1000000007, InternalMath.PrimitiveRoot <Mod1000000007>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(469762049, InternalMath.PrimitiveRoot <Mod469762049>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(167772161, InternalMath.PrimitiveRoot <Mod167772161>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(754974721, InternalMath.PrimitiveRoot <Mod754974721>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(324013369, InternalMath.PrimitiveRoot <Mod324013369>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(831143041, InternalMath.PrimitiveRoot <Mod831143041>()).Should().BeTrue();
     MathUtil.IsPrimitiveRoot(1685283601, InternalMath.PrimitiveRoot <Mod1685283601>()).Should().BeTrue();
 }
        public void InvGcdBound()
        {
            var pred = new List <long>();

            for (int i = 0; i <= 10; i++)
            {
                pred.Add(i);
                pred.Add(-i);
                pred.Add(long.MinValue + i);
                pred.Add(long.MaxValue - i);

                pred.Add(long.MinValue / 2 + i);
                pred.Add(long.MinValue / 2 - i);
                pred.Add(long.MaxValue / 2 + i);
                pred.Add(long.MaxValue / 2 - i);

                pred.Add(long.MinValue / 3 + i);
                pred.Add(long.MinValue / 3 - i);
                pred.Add(long.MaxValue / 3 + i);
                pred.Add(long.MaxValue / 3 - i);
            }
            pred.Add(998244353);
            pred.Add(1_000_000_007);
            pred.Add(1_000_000_009);
            pred.Add(-998244353);
            pred.Add(-1_000_000_007);
            pred.Add(-1_000_000_009);

            foreach (var a in pred)
            {
                foreach (var b in pred)
                {
                    if (b <= 0)
                    {
                        continue;
                    }
                    long a2 = InternalMath.SafeMod(a, b);
                    (long first, long second) = InternalMath.InvGCD(a, b);
                    var g = Gcd(a2, b);
                    first.Should().Be(g);
                    second.Should().BeGreaterOrEqualTo(0);

                    (b / first).Should().BeGreaterOrEqualTo(second);
                    ((long)(new BigInteger(second) * a2 % b)).Should().Be(g % b);
                }
            }
        }
        public void IsPrime()
        {
            InternalMath.IsPrime(121).Should().BeFalse();
            InternalMath.IsPrime(11 * 13).Should().BeFalse();
            InternalMath.IsPrime(1_000_000_007).Should().BeTrue();
            InternalMath.IsPrime(1_000_000_008).Should().BeFalse();
            InternalMath.IsPrime(1_000_000_009).Should().BeTrue();

            for (int i = 0; i <= 10000; i++)
            {
                InternalMath.IsPrime(i).Should().Be(IsPrimeNaive(i));
            }
            for (int i = 0; i <= 10000; i++)
            {
                int x = int.MaxValue - i;
                InternalMath.IsPrime(x).Should().Be(IsPrimeNaive(x));
            }
        }
        private static StaticModInt <T>[] CalcurateSumIE()
        {
            int g    = InternalMath.PrimitiveRoot <T>();
            int cnt2 = InternalBit.BSF(default(T).Mod - 1);
            var e    = new StaticModInt <T>(g).Pow((default(T).Mod - 1) >> cnt2);
            var ie   = e.Inv();

            var sumIE = new StaticModInt <T> [30];

            // es[i]^(2^(2+i)) == 1
            Span <StaticModInt <T> > es =
#if !NETCOREAPP3_0_OR_GREATER
                new
#else
                stackalloc
#endif
                StaticModInt <T> [cnt2 - 1];
            Span <StaticModInt <T> > ies =
#if !NETCOREAPP3_0_OR_GREATER
                new
#else
                stackalloc
#endif
                StaticModInt <T> [cnt2 - 1];

            for (int i = es.Length - 1; i >= 0; i--)
            {
                // e^(2^(2+i)) == 1
                es[i]  = e;
                ies[i] = ie;
                e     *= e;
                ie    *= ie;
            }

            var now = StaticModInt <T> .Raw(1);

            for (int i = 0; i <= cnt2 - 2; i++)
            {
                sumIE[i] = ies[i] * now;
                now     *= es[i];
            }

            return(sumIE);
        }
 public void PrimitiveRootTestNaive()
 {
     for (int m = 2; m <= 10000; m++)
     {
         if (!InternalMath.IsPrime(m))
         {
             continue;
         }
         //int n = InternalMath.PrimitiveRoot(m);
         int n = mods[m].PrimitiveRoot();
         n.Should().BeGreaterOrEqualTo(1);
         m.Should().BeGreaterThan(n);
         int x = 1;
         for (int i = 1; i <= m - 2; i++)
         {
             x = (int)((long)x * n % m);
             // x == n^i
             x.Should().NotBe(1);
         }
         x = (int)((long)x * n % m);
         x.Should().Be(1);
     }
 }