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 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]); }
public override IEnumerable <object> Solve(TextReader inputStream) { var(n, k) = inputStream.ReadValue <int, int>(); var a = inputStream.ReadIntArray(); var bit = new BinaryIndexedTree(2001); var count = Modular.Zero; foreach (var ai in a) { count += bit.Sum((ai + 1)..); bit.AddAt(ai, 1); } count *= k; foreach (var ai in a) { count += bit.Sum((ai + 1)..) * new Modular(k) * new Modular(k - 1) / new Modular(2); } yield return(count); }
public void BITAddTest() { 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 i = 0; i < sum.Length; i++) { Assert.Equal(sum[i], bit.Sum(i)); } bit.AddAt(2, 3); a[2] += 3; sum = GetPrefixSum(a); Assert.Equal(a.Length, bit.Length); for (int i = 0; i < sum.Length; i++) { Assert.Equal(sum[i], bit.Sum(i)); Assert.Equal(sum[i], bit.Sum(^ (a.Length - i))); } }