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); } }
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); } }
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); } }
/// <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); }
private TValue Sum(int r) { TValue s = default; for (; r > 0; r -= InternalBit.ExtractLowestSetBit(r)) { s = op.Add(s, data[r]); } return(s); }
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); } } }
public Deque(int capacity) { if (capacity <= 8) { capacity = 8; } else { capacity = 1 << (InternalBit.CeilPow2(capacity + 1)); } data = new T[capacity]; mask = capacity - 1; }
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>(); }
/// <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); }
public Impl(int length) { S = Math.Max(1 << InternalBit.CeilPow2(length), B); S8 = S / 8; }
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); } }