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); }
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); }
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); }
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); }