Problem:
Score : 600 points

Problem Statement

You are given an integer sequence of length N, a = {a_1, a_2, …, a_N}, and an integer K.

a has N(N+1)/2 non-empty contiguous subsequences, {a_l, a_{l+1}, …, a_r} (1 ≤ l ≤ r ≤ N). Among them, how many have an arithmetic mean that is greater than or equal to K?

Constraints

All input values are integers.

1 ≤ N ≤ 2 \times 10^5

1 ≤ K ≤ 10^9

1 ≤ a_i ≤ 10^9

Input

Input is given from Standard Input in the following format:

N K
a_1
a_2
:
a_N

Output

Print the number of the non-empty contiguous subsequences with an arithmetic mean that is greater than or equal to K.

Sample Input 1

3 6
7
5
7

Sample Output 1

5

All the non-empty contiguous subsequences of a are listed below:

{a_1} = {7}

{a_1, a_2} = {7, 5}

{a_1, a_2, a_3} = {7, 5, 7}

{a_2} = {5}

{a_2, a_3} = {5, 7}

{a_3} = {7}

Their means are 7, 6, 19/3, 5, 6 and 7, respectively, and five among them are 6 or greater. Note that {a_1} and {a_3} are indistinguishable by the values of their elements, but we count them individually.

Sample Input 2

1 2
1

Sample Output 2

0

Sample Input 3

7 26
10
20
30
40
30
20
10

Sample Output 3

13

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace AtCoder.ARC075
{
    class MeaningfulMean
    {
        public static void Main()
        {
            var nk = ReadLine().Trim().Split(' ').Select(i => int.Parse(i)).ToArray();
            var a = new int[nk[0]].Select(_ => long.Parse(ReadLine().Trim())).ToArray();
            WriteLine(Solve(nk[0], nk[1], a));
        }
        class CoordinateCompresser
        {
            Dictionary<long, int> _CoordinateToRank;
            public int CoordinateToRank(long pos)
            {
                return _CoordinateToRank[pos];
            }
            public CoordinateCompresser(long[] pos, bool discending = false)
            {
                var rankToCoordinate = (discending) ? pos.OrderByDescending(_ => _).ToArray() : pos.OrderBy(_ => _).ToArray();
                _CoordinateToRank = new Dictionary<long, int>();
                for (var i = 0; i < rankToCoordinate.Length; ++i)
                    _CoordinateToRank.Add(rankToCoordinate[i], i);
                Length = rankToCoordinate.Length;
            }
            public int Length
            {
                get;
                private set;
            }
        }
        static long Solve(int n, int k, long[] a)
        {
            long sum = 0;
            var adiff = a.Select(_ => _ - k).Select(_ => sum += _).ToArray();
            var compresser = new CoordinateCompresser(adiff.Distinct().ToArray(), true);
            var bit = new BITWithCoordinateCompress(compresser);
            var partialBit = new BITWithCoordinateCompress(compresser);
            foreach (var diff in adiff)
                bit.Increment(diff);
            long res = (adiff.Any(_ => _ == 0)) ? bit[0] : 0;
            foreach(var diff in adiff) {
                partialBit.Increment(diff);
                res += bit[diff] - partialBit[diff];
            }
            return res;
        }
        class BITWithCoordinateCompress
        {
            BinaryIndexedTree bit;
            CoordinateCompresser comp;
            public BITWithCoordinateCompress(CoordinateCompresser compressor)
            {
                bit = new BinaryIndexedTree(compressor.Length);
                comp = compressor;
            }
            public void Increment(long pos)
            {
                bit.Add(comp.CoordinateToRank(pos), 1);
            }
            public int this[long pos]
            {
                get
                {
                    return bit[comp.CoordinateToRank(pos)];
                }
            }
        }
        class BinaryIndexedTree
        {
            int[] array;
            public BinaryIndexedTree(int size)
            {
                array = new int[size];
            }
            public void Add(int idx, int num)
            {
                for (Index index = idx; 0 <= index && index < array.Length; index.MoveUp()) {
                    array[index] += num;
                }
            }
            public int this[int idx]
            {
                get {
                    int res = 0;
                    for (Index index = idx; index >= 0; index.MoveLeft()) {
                        res += array[index];
                    }
                    return res;
                }
            }
            struct Index
            {
                int idx;
                Index(int index)
                {
                    idx = index;
                }
                public static implicit operator Index(int index)
                {
                    return new Index(index);
                }
                public static implicit operator int(Index index)
                {
                    return index.idx;
                }
                public void MoveUp()
                {
                    idx += (idx + 1) & (~idx);
                }
                public void MoveLeft()
                {
                    idx -= (idx + 1) & (~idx);
                }

            }
        }
    }
}