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. 2
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. 3
0
        public static int getNum(string str)
        {
            int n = str.Length;

            int[] sum = new int[n];

            sum[0] = str[0] == 'a' ? 1 : str[0] == 'c' ? -1 : 0;

            for (int i = 1; i < n; i++)
            {
                int value = str[i] == 'a' ? 1 : str[i] == 'c' ? -1 : 0;
                sum[i] += sum[i - 1] + value;
            }

            var sortedSum = new HashSet <int>(sum).ToArray();

            Array.Sort(sortedSum);
            int size = sortedSum.Length;

            BinaryIndexedTree binaryIndexedTree = new BinaryIndexedTree(size);

            int res = 0;

            for (int i = 0; i < n; i++)
            {
                int idx  = Array.BinarySearch(sortedSum, sum[i]);
                int tsum = sum[i] > 0 ? 1 : 0;

                if (idx > 0)
                {
                    tsum = (tsum + binaryIndexedTree.query(idx - 1)) % mod;
                }

                res = (res + tsum) % mod;

                binaryIndexedTree.update(idx, 1);
            }

            return(res);
        }
        /// <summary>
        /// get all the result into an array
        /// </summary>
        /// <param name="intervals">All the segments [L, R]</param>
        /// <param name="queries">All the queries (K, X)</param>
        /// <returns></returns>
        public static int[] getResult(List <Interval> intervals, List <Query> queries)
        {
            n          = intervals.Count;
            size       = new int[n];
            sortedSize = new int[n];

            for (int i = 0; i < n; i++)
            {
                size[i]       = intervals[i].Right - intervals[i].Left + 1;
                sortedSize[i] = size[i];
            }

            var dataList = new List <int>();

            q = queries.Count;

            for (int i = 0; i < q; i++)
            {
                dataList.Add(queries[i].Point);
            }

            for (int i = 0; i < n; i++)
            {
                dataList.Add(intervals[i].Left);
                dataList.Add(intervals[i].Right);
            }

            datas = dataList.ToArray();
            Array.Sort(datas);
            Array.Sort(sortedSize);

            maxn = datas.Length + 2;
            cnt  = new int[maxn];

            for (int i = 0; i < n; i++)
            {
                intervals[i].Left  = Array.BinarySearch(datas, intervals[i].Left);
                intervals[i].Right = Array.BinarySearch(datas, intervals[i].Right);
                size[i]            = Array.BinarySearch(sortedSize, size[i]) + 1;
                cnt[intervals[i].Left]++;
                cnt[intervals[i].Right + 1]++;
            }

            al = new Pair[maxn][];

            for (int i = 0; i < maxn; i++)
            {
                al[i]  = new Pair[cnt[i]];
                cnt[i] = 0;
            }

            for (int i = 0; i < n; i++)
            {
                int curr1 = intervals[i].Left, curr2 = intervals[i].Right + 1;

                al[curr1][cnt[curr1]++] = new Pair(size[i], 1);

                al[curr2][cnt[curr2]++] = new Pair(size[i], -1);
            }

            cnt.Fill(0);

            for (int i = 0; i < q; i++)
            {
                queries[i].Point = Array.BinarySearch(datas, queries[i].Point);

                cnt[queries[i].Point]++;
            }

            qr = new Pair[maxn][];
            for (int i = 0; i < maxn; i++)
            {
                qr[i]  = new Pair[cnt[i]];
                cnt[i] = 0;
            }

            for (int i = 0; i < q; i++)
            {
                int curr = queries[i].Point;

                qr[curr][cnt[curr]++] = new Pair(i, queries[i].K);
            }

            binaryIndexedTree = new BinaryIndexedTree(n);

            res = new int[q];

            for (int i = 0; i < maxn; i++)
            {
                foreach (Pair pair in al[i])
                {
                    binaryIndexedTree.update(pair.Index, pair.Value);
                }

                foreach (Pair query in qr[i])
                {
                    int k = query.Value, low = 1, high = n;

                    while (low < high)
                    {
                        int mid = (low + high) >> 1;

                        if (binaryIndexedTree.query(mid) >= k)
                        {
                            high = mid;
                        }
                        else
                        {
                            low = mid + 1;
                        }
                    }

                    res[query.Index] = binaryIndexedTree.query(low) >= k ? low : -1;
                }
            }

            for (int i = 0; i < q; i++)
            {
                res[i] = res[i] == -1 ? -1 : sortedSize[res[i] - 1];
            }

            return(res);
        }
        public static List <long> GetResult(int[][] queries, int[] ns)
        {
            int n              = ns.Length;
            var bit            = new BinaryIndexedTree(ns);
            var bitTriangleAsc = new BinaryIndexedTree(n);
            var bitTriangleDes = new BinaryIndexedTree(n);

            for (int i = 0; i < n; i++)
            {
                bitTriangleAsc.update(i, ns[i] * (i + 1));
                bitTriangleDes.update(i, ns[i] * (n - i));
            }

            var res = new List <long>();

            for (int i = 0; i < queries.GetLength(0); i++)
            {
                var query = queries[i];

                if (query[0] == 1)
                {
                    int l = query[1] - 1;
                    int r = query[2] - 1;
                    int k = query[3];

                    int top      = Math.Min(k + 1, r - l + 1);
                    int left     = l - k;
                    int topLeft  = left + top - 1;
                    int topRight = r - top + 1;

                    int valueZero = 0;

                    if (left < 0)
                    {
                        valueZero = -left;
                        left      = 0;
                    }

                    if (topLeft < 0)
                    {
                        topLeft   = 0;
                        valueZero = 0;
                    }

                    var tmpRes = bitTriangleAsc.query(topLeft - 1) - bitTriangleAsc.query(left - 1);

                    if (valueZero > 0)
                    {
                        tmpRes += (bit.query(topLeft - 1) - bit.query(left - 1)) * valueZero;
                    }
                    else
                    {
                        tmpRes -= (bit.query(topLeft - 1) - bit.query(left - 1)) * left;
                    }

                    tmpRes += (bit.query(topRight) - bit.query(topLeft - 1)) * top;
                    tmpRes += bitTriangleDes.query(r) - bitTriangleDes.query(topRight);
                    tmpRes -= (bit.query(r) - bit.query(topRight)) * (n - r - 1);
                    res.Add(tmpRes);
                }
                else
                {
                    int idx = query[1] - 1;
                    int val = query[2];

                    if (ns[idx] != val)
                    {
                        int addValue = val - ns[idx];
                        bit.update(idx, addValue);
                        bitTriangleAsc.update(idx, addValue * (idx + 1));
                        bitTriangleDes.update(idx, addValue * (n - idx));

                        ns[idx] = val;
                    }
                }
            }

            return(res);
        }
Esempio n. 6
0
        public static List <int> getResult(int[] ns, int x, int[][] queries)
        {
            int n = ns.Length;

            BinaryIndexedTree binaryIndexedTree = new BinaryIndexedTree(n);

            for (int i = 0; i < n; i++)
            {
                if (ns[i] == x)
                {
                    binaryIndexedTree.update(i, 1);
                }
            }

            List <int> res = new List <int>();

            for (int i = 0; i < queries.Length; i++)
            {
                int[] tmp  = queries[i];
                int   type = tmp[0];
                if (type == 1)
                {
                    int l    = tmp[1];
                    int r    = tmp[2];
                    int k    = tmp[3];
                    int numL = binaryIndexedTree.query(l - 1);
                    int numR = binaryIndexedTree.query(r);

                    if (numR >= numL + k)
                    {
                        int low  = l;
                        int high = r;

                        int sum = numL + k;

                        int mid = 0;

                        while (low < high)
                        {
                            mid = (low + high) >> 1;

                            if (binaryIndexedTree.query(mid) >= sum)
                            {
                                high = mid;
                            }
                            else
                            {
                                low = mid + 1;
                            }
                        }

                        res.Add(low);
                    }
                    else
                    {
                        res.Add(-1);
                    }
                }
                else
                {
                    int index = tmp[1] - 1;
                    int value = tmp[2];

                    if (ns[index] == x && value != x)
                    {
                        binaryIndexedTree.update(index, -1);
                    }

                    if (ns[index] != x && value == x)
                    {
                        binaryIndexedTree.update(index, 1);
                    }

                    ns[index] = value;
                }
            }

            return(res);
        }