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++14 (Clang 3.8.0) (judge verdict: Accepted)

//
//  main.cpp
//

#include <algorithm>
#include <array>
#include <assert.h>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <memory>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = int64_t;
using ull = uint64_t;
constexpr ll LL_MAX = numeric_limits<ll>::max();
constexpr ull ULL_MAX = numeric_limits<ull>::max();

template<typename T>
vector<T> make_vec_nd(T init, ll size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, ll size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

#define rep(i, a, b) for (ll i = (a); i < (b); i++)
#define rrep(i, a, b) for (ll i = (a)-1; i >= (b); i--)

template<typename Monoid>
struct SegmentTree {
    using Op = function<Monoid(const Monoid& lhs, const Monoid& rhs)>;
    ll width;
    vector<Monoid> node;
    Op op;
    Monoid unit;
    
    SegmentTree(ll N, Op op, Monoid unit)
    : SegmentTree(vector<Monoid>(N, unit), op, unit) {}
    SegmentTree(const vector<Monoid>& elems, Op op, Monoid unit)
    : op(op)
    , unit(unit) {
        width = 1;
        while (width < elems.size()) {
            width *= 2;
        }
        node.resize(2 * width - 1, unit);
        for (size_t i = 0; i < elems.size(); i++) {
            node[i + width - 1] = elems[i];
        }
        for (size_t i = width - 2; i != numeric_limits<size_t>::max(); i--) {
            node[i] = op(node[2 * i + 1], node[2 * i + 2]);
        }
    }
    void update(ll idx, Monoid elem) {
        idx += width - 1;
        node[idx] = elem;
        while (idx >= 1) {
            idx = (idx - 1) / 2;
            node[idx] = op(node[2 * idx + 1], node[2 * idx + 2]);
        }
    }
    Monoid query(ll a, ll b, ll root = 0) const {
        assert(0 <= a && b <= width);
        ll left = root, right = root;
        while (left < width - 1) {
            left = 2 * left + 1;
        }
        left -= (width - 1);
        while (right < width - 1) {
            right = 2 * right + 2;
        }
        right -= (width - 1);
        right++;
        if (right <= a || b <= left) {
            return unit;
        }
        if (a <= left && right <= b) {
            return node[root];
        }
        Monoid ans_l = query(a, b, 2 * root + 1);
        Monoid ans_r = query(a, b, 2 * root + 2);
        return op(ans_l, ans_r);
    }
    Monoid operator[](size_t idx) { return query(idx, idx + 1); }
};

int main() {
    ll N, K;
    cin >> N >> K;
    vector<ll> As(N);
    rep(i,0,N) {
        cin >> As[i];
        As[i] -= K;
    }
    struct Sum {
        ll idx;
        ll value;
    };
    vector<Sum> sums(N+1);
    rep(n,1,N+1) {
        sums[n].value = sums[n-1].value + As[n-1];
        sums[n].idx = n;
    }
    sort(sums.begin(), sums.end(), [](Sum& lhs, Sum& rhs){ return lhs.value < rhs.value || (lhs.value == rhs.value && lhs.idx < rhs.idx); });
    SegmentTree<ll> tree(N+1, [](ll lhs, ll rhs){ return lhs + rhs; }, 0);
    ll ans = 0;
    rrep(i,sums.size(),0) {
        ans += tree.query(sums[i].idx, sums.size());
        tree.update(sums[i].idx, 1);
    }
    cout << ans << endl;
}