private static void Add(T[] data, int p, T w)
 {
     for (++p; p < data.Length; p += (int)InternalBit.ExtractLowestSetBit(p))
     {
         data[p] = op.Add(data[p], w);
     }
 }
Esempio n. 2
0
 public void Add(int p, TValue x)
 {
     Debug.Assert(unchecked ((uint)p < data.Length));
     for (p++; p < data.Length; p += InternalBit.ExtractLowestSetBit(p))
     {
         data[p] = op.Add(data[p], x);
     }
 }
Esempio n. 3
0
 public void Add(int p, TValue x)
 {
     Contract.Assert((uint)p < (uint)Length, reason: $"IndexOutOfRange: 0 <= {nameof(p)} && {nameof(p)} < Length");
     for (++p; p < data.Length; p += (int)InternalBit.ExtractLowestSetBit(p))
     {
         data[p] = op.Add(data[p], x);
     }
 }
Esempio n. 4
0
 /// <summary>
 /// 長さ <paramref name="n"/> の数列 a を持つ <see cref="Segtree{TValue, TOp}"/> クラスの新しいインスタンスを作ります。初期値は <see cref="TOp.Identity"/> です。
 /// </summary>
 /// <remarks>
 /// <para>制約: 0≤<paramref name="n"/>≤10^8</para>
 /// <para>計算量: O(<paramref name="n"/>)</para>
 /// </remarks>
 /// <param name="n">配列の長さ</param>
 public Segtree(int n)
 {
     Length = n;
     log    = InternalBit.CeilPow2(n);
     size   = 1 << log;
     d      = new TValue[2 * size];
     Array.Fill(d, op.Identity);
 }
Esempio n. 5
0
        private TValue Sum(int r)
        {
            TValue s = default;

            for (; r > 0; r -= InternalBit.ExtractLowestSetBit(r))
            {
                s = op.Add(s, data[r]);
            }
            return(s);
        }
Esempio n. 6
0
 public void Add(int h, int w, T v)
 {
     for (var hh = h + 1; hh < tree.Length; hh += (int)InternalBit.ExtractLowestSetBit(hh))
     {
         for (var ww = w + 1; ww < tree[hh].Length; ww += (int)InternalBit.ExtractLowestSetBit(ww))
         {
             tree[hh][ww] = op.Add(tree[hh][ww], v);
         }
     }
 }
Esempio n. 7
0
 public Deque(int capacity)
 {
     if (capacity <= 8)
     {
         capacity = 8;
     }
     else
     {
         capacity = 1 << (InternalBit.CeilPow2(capacity + 1));
     }
     data = new T[capacity];
     mask = capacity - 1;
 }
Esempio n. 8
0
        public void Simple()
        {
            var deque = new Deque <int>();

            deque.data.Should().HaveCount(8);
            deque.Should().HaveCount(0);

            deque.Invoking(deque => deque.PopLast()).Should().Throw <InvalidOperationException>();
            deque.Invoking(deque => deque.PopFirst()).Should().Throw <InvalidOperationException>();

            for (int i = 1; i < 8; i++)
            {
                deque.AddLast(i);
                deque.Last.Should().Be(i);
                deque.data.Should().HaveCount(8);
                deque.Should().HaveCount(i);
            }
            deque.Add(-1);
            deque.data.Should().HaveCount(16);
            deque.Should().HaveCount(8);
            for (int i = deque.Count + 1; i <= 10000; i++)
            {
                deque.AddFirst(i);
                deque.First.Should().Be(i);
                deque.Last.Should().Be(-1);
                deque.data.Should().HaveCount(1 << InternalBit.CeilPow2(i + 1));
                deque.Should().HaveCount(i);
            }

            var cap = 1 << InternalBit.CeilPow2(10000);

            for (int i = deque.Count - 1; i >= 8; i--)
            {
                deque.PopFirst().Should().Be(i + 1);
                deque.data.Should().HaveCount(cap);
                deque.Should().HaveCount(i);
            }

            deque.PopLast().Should().Be(-1);

            for (int i = deque.Count - 1; i >= 0; i--)
            {
                deque.PopLast().Should().Be(i + 1);
                deque.data.Should().HaveCount(cap);
                deque.Should().HaveCount(i);
            }

            deque.Invoking(deque => deque.PopLast()).Should().Throw <InvalidOperationException>();
            deque.Invoking(deque => deque.PopFirst()).Should().Throw <InvalidOperationException>();
        }
Esempio n. 9
0
        /// <summary>
        /// 使用する <paramref name="xs"/> の値を初期化します。<paramref name="xs"/> はソート済みであること。
        /// </summary>
        public ConvexHullTrick(T[] xs, T xinf, T yinf)
        {
            Length = xs.Length;
            XINF   = xinf;
            YINF   = yinf;

            size = 1 << InternalBit.CeilPow2(Length);
            int n2 = size << 1;

            u       = new bool[n2];
            this.xs = new T[n2];
            xs.AsSpan().CopyTo(this.xs);
            this.xs.AsSpan(Length).Fill(XINF);
            p = new T[n2];
            q = new T[n2];
        }
        /// <summary>
        /// 長さ <paramref name="n"/> の数列 a を持つ <see cref="SLazySegtree{TValue, F, TOp}"/> クラスの新しいインスタンスを作ります。初期値は <c>Identity</c> です。
        /// </summary>
        /// <remarks>
        /// <para>制約: 0≤<paramref name="n"/>≤10^8</para>
        /// <para>計算量: O(<paramref name="n"/>)</para>
        /// </remarks>
        /// <param name="n">配列の長さ</param>
        public SLazySegtree(int n)
        {
            Length = n;
            log    = InternalBit.CeilPow2(n);
            size   = 1 << log;
            d      = new TValue[2 * size];
            lz     = new F[size];
            Array.Fill(d, op.Identity);
            Array.Fill(lz, op.FIdentity);

            valSize = new int[2 * size];
            Array.Fill(valSize, 1, size, n);
            for (int i = size - 1; i >= 1; i--)
            {
                valSize[i] = valSize[2 * i] + valSize[2 * i + 1];
            }
        }
        private static StaticModInt <TMod>[] ConvolutionFFT <TMod>(ReadOnlySpan <StaticModInt <TMod> > a, ReadOnlySpan <StaticModInt <TMod> > b)
            where TMod : struct, IStaticMod
        {
            int n = a.Length, m = b.Length;
            int z  = 1 << InternalBit.CeilPow2(n + m - 1);
            var a2 = new StaticModInt <TMod> [z];
            var b2 = new StaticModInt <TMod> [z];

            a.CopyTo(a2);
            b.CopyTo(b2);

            var result = ConvolutionFFTInner(a2, b2);

            Array.Resize(ref result, n + m - 1);
            var iz = new StaticModInt <TMod>(z).Inv();

            for (int i = 0; i < result.Length; i++)
            {
                result[i] *= iz;
            }

            return(result);
        }
Esempio n. 12
0
 public Impl(int length)
 {
     S  = Math.Max(1 << InternalBit.CeilPow2(length), B);
     S8 = S / 8;
 }
Esempio n. 13
0
        public static uint[] Convolution <TMod>(ReadOnlySpan <uint> a, ReadOnlySpan <uint> b)
            where TMod : struct, IStaticMod
        {
            var mod = default(TMod).Mod;

            if (default(TMod).IsPrime && a.Length + b.Length - 1 <= (1 << InternalBit.BSF(mod - 1)))
            {
                // ACL で解けるならOK
                return(MathLib.Convolution <TMod>(a, b));
            }
            unchecked
            {
                var n = a.Length;
                var m = b.Length;

                var la = new long[n];
                for (int i = 0; i < la.Length; i++)
                {
                    la[i] = a[i] % mod;
                }
                var lb = new long[m];
                for (int i = 0; i < lb.Length; i++)
                {
                    lb[i] = b[i] % mod;
                }

                if (n == 0 || m == 0)
                {
                    return(Array.Empty <uint>());
                }

                const long Mod1 = 167772161;
                const long Mod2 = 469762049;
                const long Mod3 = 754974721;

                const long M1i2  = 104391568;
                const long M12i3 = 190329765;
                long       M12i  = (long)(ulong)(Mod1 * Mod2) % mod;

                Debug.Assert(default(FFTMod1).Mod == Mod1);
                Debug.Assert(default(FFTMod2).Mod == Mod2);
                Debug.Assert(default(FFTMod3).Mod == Mod3);
                Debug.Assert(M1i2 == new StaticModInt <FFTMod2>(Mod1).Inv().Value);
                Debug.Assert(M12i3 == new StaticModInt <FFTMod3>(Mod1 * Mod2).Inv().Value);

                var c1 = MathLib.Convolution <FFTMod1>(la, lb);
                var c2 = MathLib.Convolution <FFTMod2>(la, lb);
                var c3 = MathLib.Convolution <FFTMod3>(la, lb);

                var c = new uint[n + m - 1];
                for (int i = 0; i < c.Length; i++)
                {
                    var v1 = ((c2[i] - c1[i]) * M1i2) % Mod2;
                    if (v1 < 0)
                    {
                        v1 += Mod2;
                    }
                    var v2 = (c3[i] - (c1[i] + Mod1 * v1) % Mod3) * M12i3 % Mod3;
                    if (v2 < 0)
                    {
                        v2 += Mod3;
                    }
                    var x = (c1[i] + Mod1 * v1 + M12i * v2) % mod;
                    if (x < 0)
                    {
                        x += mod;
                    }

                    c[i] = (uint)x;
                }

                return(c);
            }
        }