public void GivenArrayWhenConstructBinaryIndexedTreeThenNoExceptions()
        {
            var tree = new BinaryIndexedTree <int>(new[] { 1, 2, 3, 4 }, Plus, Minus);

            Assert.NotNull(tree);
            Assert.Equal(4, tree.Count);
        }
Esempio n. 2
0
    public void Solve()
    {
        int N = Reader.Int();

        int[] X = new int[N], V = new int[N];
        for (int i = 0; i < N; i++)
        {
            X[i] = Reader.Int(); V[i] = Reader.Int();
        }
        V = Compress(V);
        Array.Sort(X, V);
        int[] L = new int[N], R = new int[N];

        for (int i = 0, max = -1; i < N; i++)
        {
            R[i] = max = Math.Max(max, V[i] + 1);
        }
        for (int i = N - 1, min = int.MaxValue; i >= 0; i--)
        {
            L[i] = min = Math.Min(min, V[i]);
        }

        var BIT = new BinaryIndexedTree(N + 1, Mod);

        BIT.Add(0, 1);
        for (int i = 0; i < N; i++)
        {
            BIT.Add(R[i], BIT.Sum(L[i], R[i] + 1));
        }

        Console.WriteLine(BIT.Sum(N, N + 1));
    }
        public static long GetNum(int[] ns)
        {
            int n = ns.Length;

            var sortedNs = new int[n];

            for (int j = 0; j < n; j++)
            {
                sortedNs[j] = ns[j];
            }

            Array.Sort(sortedNs);

            for (int j = 0; j < n; j++)
            {
                ns[j] = Array.BinarySearch(sortedNs, ns[j]);
            }

            Array.Reverse(ns);

            var bit = new BinaryIndexedTree(n);

            long total = 0;

            bit.update(ns[0], 1);

            for (int j = 1; j < n; j++)
            {
                total += bit.query(ns[j] - 1);
                bit.update(ns[j], 1);
            }

            return(total);
        }
Esempio n. 4
0
        public static ulong Solve(int n, int k, int[][] edges)
        {
            foreach (var edge in edges)
            {
                edge[0]++;
                edge[1]++;
            }

            var adj = GraphHelper.ToAdjacencyList(edges, n + 1);
            var bit = new BinaryIndexedTree(n);

            var notHeads = new bool[n + 1];

            notHeads[0] = true;
            foreach (var edge in edges)
            {
                notHeads[edge[1]] = true;
            }

            var head = notHeads.FirstIndexOf(nh => !nh);

            var count = Solve_Bit_Dfs(bit, adj, head, n, k);

            return((ulong)count);
        }
Esempio n. 5
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var n          = inputStream.ReadInt();
            var a          = inputStream.ReadIntArray();
            var candidates = a.Distinct().OrderBy(ai => ai).ToArray();

            bool CanBeMedian(int m)
            {
                var isGreaterEqual = a.Select(ai => ai >= m ? 1 : -1).ToArray();
                var prefixSum      = new int[isGreaterEqual.Length + 1];

                for (int i = 0; i < isGreaterEqual.Length; i++)
                {
                    prefixSum[i + 1] = prefixSum[i] + isGreaterEqual[i];
                }

                long count = 0;
                var  bit   = new BinaryIndexedTree(2 * n + 1); // bit[n]が0を表すようオフセット

                foreach (var ps in prefixSum)
                {
                    var offsetted = ps + n;
                    count += bit.Sum(..(offsetted + 1));
                    bit.AddAt(offsetted, 1);
                }

                return(count >= ((long)n * (n + 1) / 2 + 1) / 2);
            }

            var index = SearchExtensions.BoundaryBinarySearch(i => CanBeMedian(candidates[i]), 0, candidates.Length);

            yield return(candidates[index]);
        }
Esempio n. 6
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(n, k) = inputStream.ReadValue <int, int>();
            var a = new int[n];

            for (int i = 0; i < n; i++)
            {
                a[i] = inputStream.ReadInt() - k;
            }

            var prefixSum = new long[a.Length + 1];

            for (int i = 0; i < a.Length; i++)
            {
                prefixSum[i + 1] = prefixSum[i] + a[i];
            }

            var shrinker = new CoordinateShrinker <long>(prefixSum); // 座圧
            var bit      = new BinaryIndexedTree(shrinker.Count);

            long count = 0;

            foreach (var s in prefixSum)
            {
                count += bit.Sum(..(shrinker.Shrink(s) + 1));   // 転倒数を数える
                bit[shrinker.Shrink(s)]++;
            }

            yield return(count);
        }
        public void GivenMinBinaryIndexedTreeWhenUpdateChangeValueThenIntervalUpdated()
        {
            var data = Enumerable.Range(1, 200).ToArray();
            var tree = new BinaryIndexedTree <int>(data,
                                                   (a, b) => Math.Min(a, b),
                                                   (a, b) =>
            {
                if (a > b)
                {
                    throw new Exception("Can only decrease value");
                }
                return(Math.Min(a, b));
            },
                                                   int.MaxValue
                                                   );

            for (int i = 0; i < data.Length; i++)
            {
                int min = int.MaxValue;
                for (int j = i; j < data.Length; j++)
                {
                    min = Math.Min(min, data[j]);
                    Assert.Equal(min, tree.GetOperationValueOnInterval(i, j));
                }
            }
        }
        public void GivenRandomSumBinaryIndexedTreeWhenUpdateValuesThenIntervalReturnsCorrectValues()
        {
            var rand = new Random();
            var data = new uint[64];

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (uint)rand.Next();
            }
            var tree = new BinaryIndexedTree <uint>(data, (a, b) => a + b, (a, b) => a - b);

            for (int i = 0; i < data.Length; i++)
            {
                var elem = (uint)rand.Next();
                data[i] = elem;
                tree[i] = elem;
            }

            for (int i = 0; i < data.Length; i++)
            {
                uint sum = 0;
                for (int j = i; j < data.Length; j++)
                {
                    sum += data[j];
                    Assert.Equal(sum, tree.GetOperationValueOnInterval(i, j));
                }
            }
        }
        public void BITInitializationZeroTest()
        {
            const int length = 5;
            var       bit    = new BinaryIndexedTree(length);

            Assert.Equal(length, bit.Length);
            Assert.Equal(0, bit.Sum(length));
        }
        public static void Main()
        {
            //var tree = new TreeNode<int>(20,
            //    new TreeNode<int>(44,
            //        new TreeNode<int>(17), new TreeNode<int>(41)),
            //    new TreeNode<int>(02,
            //           new TreeNode<int>(99), new TreeNode<int>(97)));

            // DFS(tree);
            // BFS(tree);
            //DFSWithStack(tree);

            //var array = new int[10];
            //var random = new Random();
            //for (int i = 0; i < array.Length; i++)
            //{
            //    array[i] = random.Next() % 100;
            //}

            //Console.WriteLine(string.Join(" ", array));
            //var heap = new BinaryHeap.BinaryHeap<int>((a, b) => a > b);

            //foreach (var element in array)
            //{
            //    heap.Insert(element);
            //    Console.Write(heap.GetTop() + " ");
            //}

            //Console.WriteLine();

            //for (int i  =0; i < array.Length; i++)
            //{
            //    array[i] = heap.GetTop();
            //    heap.RemoveTop();
            //}

            //Console.WriteLine(string.Join(" ", array));

            //var array = new int[10];
            //var random = new Random();
            //for (int i =0; i < array.Length; i++)
            //{
            //    array[i] = random.Next() % 100;
            //}

            //array.HeapSort((a, b) => a > b);

            var list = new List <int>();

            list.Add(3);
            list.Add(4);
            list.Add(5);

            var indexedTree = new BinaryIndexedTree <int>(list, (a, b) => a + b);

            Console.WriteLine(indexedTree.GetInterval(0, 3));
        }
        public void GivenBinaryIndexedTreeWhenSetOrGetThroughIndexerOutsideOfArrayThenThrowException()
        {
            var tree = new BinaryIndexedTree <int>(new[] { 1, 2, 3, 4 }, Plus, Minus);

            Assert.Throws <ArgumentOutOfRangeException>(() => tree[-1]);
            Assert.Throws <ArgumentOutOfRangeException>(() => tree[4]);
            Assert.Throws <ArgumentOutOfRangeException>(() => tree[-1] = 1);
            Assert.Throws <ArgumentOutOfRangeException>(() => tree[4]  = 1);
        }
Esempio n. 12
0
        public static long GetNum(int[] sequenceA, int[] sequenceB)
        {
            int n = sequenceA.Length;

            int size = (int)(2 * 1e5 + 1);
            var cnt  = new int[size];

            for (int i = 0; i < n; i++)
            {
                cnt[sequenceA[i]]++;
            }

            var f = new long[size];
            var c = new long[size];

            f[0] = c[0] = 1;

            for (int i = 1; i < size; i++)
            {
                f[i] = (f[i - 1] * i) % mod;
                // Modular multiplicative inverse and Fermat's little theorem
                c[i] = ModularExponentiation.ModularOfPow(f[i], mod - 2, mod);
            }

            long comb = f[n];

            for (int i = 1; i < size; ++i)
            {
                comb = (comb * c[cnt[i]]) % mod;
            }

            var bitree = new BinaryIndexedTree(size + 1);

            for (int i = 1; i < size; ++i)
            {
                bitree.update(i, cnt[i]);
            }

            long ans = 0;

            for (int i = 1; i <= n; ++i)
            {
                comb = (comb * ModularExponentiation.ModularOfPow(n - i + 1, mod - 2, mod)) % mod;
                ans  = (ans + comb * bitree.query(sequenceB[i - 1] - 1)) % mod;
                comb = (comb * cnt[sequenceB[i - 1]]) % mod;
                --cnt[sequenceB[i - 1]];

                if (cnt[sequenceB[i - 1]] < 0)
                {
                    break;
                }

                bitree.update(sequenceB[i - 1], -1);
            }

            return(ans);
        }
Esempio n. 13
0
        static BinaryIndexedTree ReadString(string a)
        {
            var bit = new BinaryIndexedTree(a.Length);

            for (var i = 0; i < a.Length; ++i)
            {
                bit.Set(i, (a[i] == 'A') ? 1 : 2);
            }
            return(bit);
        }
Esempio n. 14
0
        public void Test1()
        {
            var t = new BinaryIndexedTree(4);

            t.Update(0, 1);
            t.Update(3, 4);
            t.Query(0, 3).Should().Be(5);
            t.Query(2).Should().Be(1);
            t.Query(1, 3).Should().Be(4);
        }
        public void GetSum_CreateBITAndRequestSum_ReturnCorrect()
        {
            int[] array       = { 2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9 };
            var   tree        = new BinaryIndexedTree(array);
            var   expectedSum = 12;

            var resultedSum = tree.GetSum(5);

            resultedSum.Should().Be(expectedSum);
        }
Esempio n. 16
0
    string Solve(int N, int[] who, int[] index)
    {
        Array.Sort(index, who);
        var ans = new int[N * N];
        int L   = 0;
        var bit = new BinaryIndexedTree(N * N);

        for (int i = 0; i < N * N; i++)
        {
            bit.Add(i, 1);
        }

        for (int i = 0; i < N; i++)
        {
            if (bit.Sum(index[i]) < who[i])
            {
                return(No);
            }
            ans[index[i]] = who[i];
            bit.Add(index[i], -1);

            int num = who[i] - 1;
            for (; L < ans.Length && num > 0; L++)
            {
                if (ans[L] == 0)
                {
                    num--;
                    bit.Add(L, -1);
                    ans[L] = who[i];
                }
            }
            if (num > 0)
            {
                return(No);
            }
        }
        for (int i = 0; i < N; i++)
        {
            for (int num = N - who[i]; L < ans.Length && num > 0; L++)
            {
                if (ans[L] == 0)
                {
                    if (L < index[i])
                    {
                        return(No);
                    }
                    ans[L] = who[i];
                    num--;
                }
            }
        }

        return(Yes + "\n" + string.Join(" ", ans));
    }
Esempio n. 17
0
        public static long Solve_Bit_Dfs(BinaryIndexedTree bit, List <int>[] adj, int node, int n, int k)
        {
            var count = bit.Get(Math.Max(1, node - k), Math.Min(n, node + k));

            bit.SetDiff(node, 1);
            foreach (var child in adj[node])
            {
                count += Solve_Bit_Dfs(bit, adj, child, n, k);
            }
            bit.SetDiff(node, -1);
            return(count);
        }
Esempio n. 18
0
        public void  BinaryIndexedTreeSuccess()
        {
            int[] array = new int[] { 1, 3, 5 };

            int n = array.Length;

            var binaryTree = new BinaryIndexedTree(array);

            var result = binaryTree.RangeQuery(0, n - 1);

            Assert.AreEqual(result, 9);
        }
        public void GivenBinaryIndexedTreeWithSelectorWhenCreateTreeThenNoException()
        {
            var tree = new BinaryIndexedTree <Stub, int>(new[] { new Stub()
                                                                 {
                                                                     A = 1, B = 1
                                                                 }, new Stub()
                                                                 {
                                                                     A = 100, B = 2
                                                                 } }, Plus, Minus, (x) => x.B);

            Assert.Equal(3, tree.GetOperationValueOnInterval(0, 1));
        }
        public void TestMethod1()
        {
            int[] A = { 2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9 };

            BinaryIndexedTree biTree = new BinaryIndexedTree(A);
            var sum = biTree.GetSum(5);

            Assert.AreEqual(12, sum);

            biTree.Add(3, 6);
            sum = biTree.GetSum(5);
            Assert.AreEqual(18, sum);
        }
Esempio n. 21
0
        // Works only with comutative operation ( ex: *, + )
        public static void Main()
        {
            var binaryIndexedTree = new BinaryIndexedTree <int>(30, (a, b) => { return(a * b); });

            for (int i = 0; i < 10; i++)
            {
                binaryIndexedTree[i] = i;
            }

            Console.WriteLine(binaryIndexedTree.GetInterval(0, 5));
            Console.WriteLine(binaryIndexedTree.GetInterval(6, 10));
            Console.WriteLine(binaryIndexedTree.GetInterval(3, 7));
        }
        public void UpdateTree_UpdateTreeAndRequestSum_GetSum()
        {
            int[] array       = { 2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9 };
            var   tree        = new BinaryIndexedTree(array);
            var   expectedSum = 18;

            array[3] += 6;
            tree.UpdateTree(3, 6);

            var resultedSum = tree.GetSum(5);

            resultedSum.Should().Be(expectedSum);
        }
Esempio n. 23
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(sitesCount, queriesCount) = inputStream.ReadValue <int, int>();
            var yCoordinates = new HashSet <int>();
            var queries      = new List <Query>();
            var toAnswer     = new Queue <SumQuery>();
            var answers      = new Dictionary <SumQuery, long>();

            for (int i = 0; i < sitesCount; i++)
            {
                var(x, y, d, c) = inputStream.ReadValue <int, int, int, int>();
                yCoordinates.Add(y);
                yCoordinates.Add(y + d + 1);
                queries.Add(new AddQuery(x, y, d, c));
                queries.Add(new AddQuery(x + d + 1, y, d, -c));
            }

            for (int i = 0; i < queriesCount; i++)
            {
                var(a, b) = inputStream.ReadValue <int, int>();
                yCoordinates.Add(b);
                var query = new SumQuery(a, b);
                queries.Add(query);
                toAnswer.Enqueue(query);
            }

            queries.Sort();
            var shrinker = new CoordinateShrinker <int>(yCoordinates);
            var costs    = new BinaryIndexedTree(shrinker.Count);

            foreach (var query in queries)
            {
                var shrinkedY = shrinker.Shrink(query.Y);

                if (query is AddQuery addQuery)
                {
                    var shrinkedYPlusD = shrinker.Shrink(addQuery.Y + addQuery.Distance + 1);
                    costs.AddAt(shrinkedY, addQuery.Cost);
                    costs.AddAt(shrinkedYPlusD, -addQuery.Cost);
                }
                else if (query is SumQuery sumQuery)
                {
                    answers.Add(sumQuery, costs.Sum(shrinkedY + 1));
                }
            }

            foreach (var query in toAnswer)
            {
                yield return(answers[query]);
            }
        }
        public void BITSumFromZeroTest()
        {
            var a = new long[] { 5, 3, 7, 9, 8 };

            long[] sum = GetPrefixSum(a);

            var bit = new BinaryIndexedTree(a);

            Assert.Equal(a.Length, bit.Length);
            for (int i = 0; i < sum.Length; i++)
            {
                Assert.Equal(sum[i], bit.Sum(i));
            }
        }
    // Main function
    public static void Main(string[] args)
    {
        int[]             freq = new int[] { 2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9 };
        int               n    = freq.Length;
        BinaryIndexedTree tree = new BinaryIndexedTree();

        // Build fenwick tree from given array
        tree.constructBITree(freq, n);
        Console.WriteLine("Sum of elements in arr[0..5]" + " is = " + tree.getSum(5));
        freq[3] += 6;
        updateBIT(n, 3, 6);
        // Find sum after the value is updated
        Console.WriteLine("Sum of elements in arr[0..5]" + " after update is = " + tree.getSum(5));
    }
        public void GivenSumBinaryIndexedTreeWhenAskOperationOnIntervalThenReturnCorrectValues()
        {
            var data = Enumerable.Range(1, 200).ToArray();
            var tree = new BinaryIndexedTree <int, int>(data, (a, b) => a + b, (a, b) => a - b, (x) => x);

            for (int i = 0; i < data.Length; i++)
            {
                int sum = 0;
                for (int j = i; j < data.Length; j++)
                {
                    sum += data[j];
                    Assert.Equal(sum, tree.GetOperationValueOnInterval(i, j));
                }
            }
        }
Esempio n. 27
0
        long Check(int n, int[][] ab, BitSet flip)
        {
            if (flip.Count() % 2 != 0)
            {
                return(-1);
            }

            var odds  = new List <int>();
            var evens = new List <int>();

            for (int i = 0; i < n; i++)
            {
                if (flip[i] ^ ((i & 1) == 1))
                {
                    evens.Add(ab[flip[i] ? 1 : 0][i]);
                }
                else
                {
                    odds.Add(ab[flip[i] ? 1 : 0][i]);
                }
            }

            odds.Sort();
            evens.Sort();

            var current = odds[0];

            for (int i = 1; i < n; i++)
            {
                int next = i % 2 == 0 ? odds[i >> 1] : evens[i >> 1];
                if (current > next)
                {
                    return(-1);
                }
            }

            long count = 0;
            var  bit   = new BinaryIndexedTree(51);

            for (int i = 0; i < n; i++)
            {
                var next = ab[flip[i] ? 1 : 0][i];
                count += bit.Sum((next + 1)..);
                bit[next]++;
            }

            return(count);
        }
        public void BITSumFromAnyTest()
        {
            var a   = new long[] { 5, 3, 7, 9, 8 };
            var sum = GetPrefixSum(a);

            var bit = new BinaryIndexedTree(a);

            Assert.Equal(a.Length, bit.Length);
            for (int begin = 0; begin < bit.Length; begin++)
            {
                for (int end = begin; end <= bit.Length; end++)
                {
                    Assert.Equal(sum[end] - sum[begin], bit.Sum(begin, end));
                }
            }
        }
        public void GivenSumBinaryIndexedTreeWhenUpdateChangeValueThenIntervalUpdated()
        {
            var data = Enumerable.Range(1, 200).ToArray();
            var tree = new BinaryIndexedTree <int, int>(data, (a, b) => a + b, (a, b) => a - b, (x) => x);

            data[10] = 100;
            tree[10] = 100;
            for (int i = 0; i < data.Length; i++)
            {
                int sum = 0;
                for (int j = i; j < data.Length; j++)
                {
                    sum += data[j];
                    Assert.Equal(sum, tree.GetOperationValueOnInterval(i, j));
                }
            }
        }
Esempio n. 30
0
        public static BinaryIndexedTree FromArray(int[] input)
        {
            if (input is null)
            {
                return(null);
            }

            var result = new BinaryIndexedTree(input.Length + 1);
            var index  = 0;

            foreach (var item in input)
            {
                result.SetValue(index, item);
                index++;
            }

            return(result);
        }
Esempio n. 31
0
 public long countColoring(int n, int xzero, int xmul, int xadd, int xmod, int yzero, int ymul, int yadd, int ymod)
 {
     int[] xs = new int[n], ys = new int[n];
     Point[] points = new Point[n];
     xs[0] = xzero;
     ys[0] = yzero;
     points[0] = new Point(xs[0], ys[0]);
     for (int i = 1; i < n; ++i) {
         xs[i] = (int)(((long)points[i - 1].X * xmul + xadd) % xmod);
         ys[i] = (int)(((long)points[i - 1].Y * ymul + yadd) % ymod);
         points[i] = new Point(xs[i], ys[i]);
     }
     Array.Sort(xs);
     Array.Sort(ys);
     for (int i = 0; i < n; ++i) {
         points[i].X = Array.BinarySearch(xs, points[i].X) + 1;
         points[i].Y = Array.BinarySearch(ys, points[i].Y) + 1;
     }
     Array.Sort(points);
     long count = 0;
     BinaryIndexedTree tree;
     tree = new BinaryIndexedTree(n);
     int[] countL = new int[n], countR = new int[n];
     for (int i = 0; i < n; ++i) {
         countL[i] = tree.Sum(points[i].Y);
         tree.Add(points[i].Y, 1);
     }
     tree = new BinaryIndexedTree(n);
     for (int i = n - 1; i >= 0; --i) {
         countR[i] = tree.Sum(n) - tree.Sum(points[i].Y);
         count += (long)countR[i] * (countR[i] - 1) / 2;
         count -= (long)countL[i] * countR[i];
         tree.Add(points[i].Y, 1);
     }
     return count;
 }