#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

#define REP(i,n) for(int i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
const int MOD = 1000000007;
#define MAX_N 200010

template<typename T>
class BITree {
    public:
        BITree(int n) : m_N(n + 1) { m_Tree.assign(m_N, 0); }
        // [1, i] の合計値を返す (log m_N)
        // 閉区間であることに注意
        T Sum(int i) {
            if(i < 1 || i >= m_N) { return 0; }
            T s = 0;
            while(i > 0) { s += m_Tree[i]; i -= i & -i; }
            return s;
        }
        // [i, j] の合計値を返す (log m_N)
        // i < j
        // 閉区間であることに注意
        T Sum(int i, int j) {
            if(i > j) { return 0; }
            return Sum(j) - Sum(i-1);
        }
        // i 番目の要素(1-indexed)に x を足して更新 O(log m_N)
        void Add(int i, T x){ while(i < m_N) { m_Tree[i] += x; i += i & -i; } }
    private:
        int m_N;            // 要素数
        vector<T> m_Tree;   // BIT 本体
};

// v の各値を数値の大小関係はそのままに 1 から v.size() の範囲に圧縮する
template<typename T>
vector<T> VectorNormalization(const vector<T>& v) {
    vector<T> cp;
    vector<T> sorted;
    copy(v.begin(), v.end(), back_inserter(cp));
    copy(cp.begin(), cp.end(), back_inserter(sorted));
    sort(sorted.begin(), sorted.end());
    map<T, int> val_to_ind;
    for(int i = 0; i < sorted.size(); ++i) {
        if(val_to_ind.count(sorted[i]) == 0) { val_to_ind[sorted[i]] = i + 1; }
    }
    for(int i = 0; i < cp.size(); ++i) { cp[i] = val_to_ind[cp[i]]; }
    return std::move(cp);
}

// ある数列で x より左の x より大きい値の個数を求める
// out_v :  結果が入る vector 。 out_v[i] … i より左にある out_v[i] より大きい値の個数が入る
// p :      元の数列 (1 以上の整数)
// メモリ量 :   max(p のサイズ, p の最大値) * sizeof(T)
// 計算量 :     O(p.size() log max(p[i])) (1..N の順列なら N log N くらい)
template<typename T>
void GetLeftBiggerCnt1(vector<T>& out_v, const vector<T>& p) {
    vector<T> norm = VectorNormalization(p);
    out_v.assign(norm.size(), 0);
    T max_val = 0;
    for(auto& val : norm) { max_val = max(max_val, val); }
    BITree<T> bit(max_val);    // 以左に現れた数を BIT で管理
    for(int i = 0; i < norm.size(); ++i) {
        // ↓の +1 を抜くと自分以上のものを数えるようにできる
        out_v[i] = bit.Sum(norm[i] + 1, max_val);  // 自分より大きいものを数える
        bit.Add(norm[i], 1);   // 現れた数を更新
    }
}


// ある数列で x より左の x 以下の値の個数を求める
// out_v :  結果が入る vector 。 out_v[i] … i より左にある out_v[i] 以下の値の個数が入る
// p :      元の数列 (1 以上の整数)
// メモリ量 :   max(p のサイズ, p の最大値) * sizeof(T)
// 計算量 :     O(p.size() log max(p[i])) (1..N の順列なら N log N くらい)
template<typename T>
void GetLeftSmallerCnt2(vector<T>& out_v, const vector<T>& p) {
    GetLeftBiggerCnt1(out_v, p);
    for(int i = 0; i < out_v.size(); ++i) { out_v[i] = i - out_v[i]; }
}

// ある数列で、連続する部分列の和が 0 以上のものの個数を求める
// p : 元の数列
// メモリ量 :   max(p のサイズ, p の最大値) * sizeof(T) * 3
// 計算量 :     O(3 * p.size() log max(p[i])) (1..N の順列なら N log N くらい)
template<typename T>
ll GetSubseqSumPositiveAndZero(vector<T>& p) {
    assert(p.size() > 0);
    // 累積和の作成
    // cs[i] が [0, i) までの累積和を表す
    vector<T> cs(p.size() + 1, 0);
    for(int i = 1; i <= p.size(); ++i) { cs[i] = cs[i-1] + p[i-1]; }
    cs = VectorNormalization(cs);   // 正規化

    // 自分より左にいる数で、自分以下の数がいくつあるか？
    // 累積和的観点から、それがイコール部分列の和が 0 以上のものの個数である
    vector<T> out_v;
    GetLeftSmallerCnt2(out_v, cs);
    ll ret = 0;
    for(int i = 0; i < out_v.size(); ++i) { ret += out_v[i]; }
    return ret;
}

ll N, K;
vector<ll> A;

signed main()
{
    cin >> N >> K;
    A.assign(N, 0);
    REP(i, N) {
        cin >> A[i];
        A[i] -= K;
    }
    printf("%lld\n", GetSubseqSumPositiveAndZero(A));

    return 0;
}


Measured memory_bytes: 19428