Esempio n. 1
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]);
            }
        }
Esempio n. 2
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. 3
0
        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)));
            }
        }