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;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        Solve();
        Console.Out.Flush();
    }
    static void Solve()
    {
        var N = sc.ReadInt();
        var K = sc.ReadLong();
        var A = sc.ReadLongArray(N);
        var sum = new long[N + 1];
        for (int i = 0; i < N; i++)
        {
            sum[i + 1] = sum[i] + A[i];
        }

        var t = new SplayTree<long>();
        for (int i = 0; i < N + 1; i++)
        {
            var x = sum[i] - K * i;
            t.Insert(x);
        }
        var ans = 0L;
        for (int i = 0; i < N; i++)
        {
            var x = sum[i] - K * i;
            var y = t.LowerBouond(x);
            var res = t.Count - y;
            ans += res - 1;
            t.Erase(x);
        }
        Console.WriteLine(ans);
    }

    class SplayTree<T> : IEnumerable<T> where T : IComparable
    {
        public Node<T> Root;
        public int Count { get { return this.Root?.Count ?? 0; } }
        public T this[int i] { get { return this.Get(i); } }
        public void Insert(T value)
        {
            var index = this.LowerBouond(value);
            var sub = Split(index, ref Root);
            var newNode = new Node<T>(value);
            var lroot = sub.Item1;
            var rroot = sub.Item2;
            var merged = Merge(ref lroot, ref newNode);
            this.Root = Merge(ref merged, ref rroot);
            newNode.Splay();
        }
        public void Erase(T value)
        {
            if (this.ValueCount(value) == 0) return;
            var sub = Split(this.LowerBouond(value), ref this.Root);
            var lroot = sub.Item1;
            var tmp = sub.Item2;
            var rroot = Split(1, ref tmp).Item2;
            this.Root = Merge(ref lroot, ref rroot);
        }
        public int LowerBouond(T value) { return LowerBouond(this.Root, value); }
        public int UpperBound(T value) { return UpperBound(this.Root, value); }
        public int ValueCount(T value) { return UpperBound(value) - LowerBouond(value); }
        public T Get(int i)
        {
            return this.GetNode(i).Value;
        }
        public Node<T> GetNode(int i)
        {
            Root = Root.GetNode(i);
            return Root;
        }
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < Count; i++) yield return this[i];
        }
        IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }

        // Node操作用静的関数 ...
        public static Node<T> GetNode(int index, Node<T> node)
        {
            if (node == null) return null;
            if (node.Count <= index) return null;
            while (true)
            {
                var lcount = node.L?.Count ?? 0;
                if (index < lcount)
                {
                    node = node.L;
                }
                else if (index == lcount)
                {
                    node.Splay();
                    return node;
                }
                else
                {
                    index -= lcount + 1;
                    node = node.R;
                }
            }
        }
        public static int LowerBouond(Node<T> root, T value)
        {
            if (root == null) return 0;
            if (value.CompareTo(root.Value) <= 0)
                return LowerBouond(root.L, value);
            else
                return (root.L?.Count ?? 0) + 1 + LowerBouond(root.R, value);
        }
        public static int UpperBound(Node<T> root, T value)
        {
            if (root == null) return 0;
            if (value.CompareTo(root.Value) >= 0)
                return (root.L?.Count ?? 0) + 1 + UpperBound(root.R, value);
            else
                return UpperBound(root.L, value);
        }
        // 2つのノードを1つにマージする
        public static Node<T> Merge(ref Node<T> lroot, ref Node<T> rroot)
        {
            if (lroot == null) return rroot;
            if (rroot == null) return lroot;

            lroot = lroot.GetNode(lroot.Count - 1);
            lroot.R = rroot;
            rroot.P = lroot;
            lroot.Update();
            return lroot;
        }
        // 与えられたノードを指定の個数で分割する
        public static Tuple<Node<T>, Node<T>> Split(int leftCount, ref Node<T> root)
        {
            if (leftCount == 0) return Tuple.Create((Node<T>)null, root);
            if (leftCount == root.Count) return Tuple.Create(root, (Node<T>)null);
            root = root.GetNode(leftCount);
            var lroot = root.L;
            var rroot = root;
            rroot.L = null;
            lroot.P = null;
            rroot.Update();
            return Tuple.Create(lroot, rroot);
        }
        // ノードの指定された位置に新しいノードを挿入する
        // 指定位置で分割して順番にマージする(l, new, r)
        public static Node<T> InsertNode(int index, Node<T> newNode, ref Node<T> root)
        {
            var trees = Split(index, ref root);
            var lroot = trees.Item1;
            var rroot = trees.Item2;
            var merged = Merge(ref lroot, ref newNode);
            return Merge(ref merged, ref rroot);
        }
        // ある位置のノードを取り除く
        public static Tuple<Node<T>, Node<T>> DeleteNode(int index, ref Node<T> root)
        {
            root = root.GetNode(index);
            var lroot = root.L;
            var rroot = root.R;
            if (lroot != null) lroot.P = null;
            if (rroot != null) rroot.P = null;
            root.R = null;
            root.L = null;
            var deleted = root;
            var merged = Merge(ref lroot, ref rroot);
            deleted.Update();
            return Tuple.Create(merged, deleted);
        }
    }
    class Node<T> : IEnumerable<T> where T : IComparable
    {
        public Node<T> P;
        public Node<T> L;
        public Node<T> R;
        public T Value;
        public int Count = 1;
        public T this[int i] { get { return GetNode(i).Value; } }
        public Node(T value) { this.Value = value; }
        public void Rotate()
        {
            var pp = P.P;
            var p = P;
            Node<T> c;
            if (p.L == this)
            {
                // 親の左が自分の場合
                c = R;
                this.R = p;
                p.L = c;
            }
            else
            {
                // 親の右が自分の場合
                c = L;
                this.L = p;
                p.R = c;
            }
            if (pp != null && pp.L == p) pp.L = this;
            if (pp != null && pp.R == p) pp.R = this;
            this.P = pp;
            p.P = this;
            if (c != null) c.P = p;

            // 状態の更新
            p.Update();
            this.Update();
        }
        public int State()
        {
            if (P == null) return 0;
            else if (P.L == this) return 1;
            else return -1;
        }
        public void Splay()
        {
            while (this.State() != 0)
            {
                if (P.State() == 0) this.Rotate();
                else if (this.State() == P.State())
                {
                    P.Rotate();
                    this.Rotate();
                }
                else
                {
                    this.Rotate();
                    this.Rotate();
                }
            }
        }
        public void Update()
        {
            // TODO: 問題によって書き換える
            this.Count = 1;
            this.Count += L?.Count ?? 0;
            this.Count += R?.Count ?? 0;
            // rmq
            //this.Min = this.Value;
            //if (L != null && Min.CompareTo(L.Value) > 0)
            //{
            //    Min = L.Value;
            //}
            //if (R != null && Min.CompareTo(R.Value) > 0)
            //{
            //    Min = R.Value;
            //}
        }
        public Node<T> GetNode(int index)
        {
            var now = this;
            while (true)
            {
                var lcount = now.L?.Count ?? 0;
                if (index < lcount)
                {
                    now = now.L;
                }
                else if (index == lcount)
                {
                    now.Splay();
                    return now;
                }
                else
                {
                    index -= lcount + 1;
                    now = now.R;
                }
            }
        }
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < this.Count; i++) yield return GetNode(i).Value;
        }
        IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
    }
    static Scanner sc = new Scanner();
}
class Scanner
{
    string[] S = new string[0];
    int Index = 0;
    char[] Separators = new char[] { ' ' };

    public string Next()
    {
        if (this.Index < this.S.Length) return this.S[this.Index++];
        var line = "";
        while (line == "") line = Console.ReadLine();
        this.S = line.Split(this.Separators, StringSplitOptions.RemoveEmptyEntries);
        if (this.S.Length == 0) return this.Next();
        this.Index = 0;
        return this.S[this.Index++];
    }
    public string ReadStr()
    {
        return this.Next();
    }
    public char ReadChar()
    {
        return this.Next()[0];
    }
    public int ReadInt()
    {
        return int.Parse(this.Next());
    }
    public uint ReadUInt()
    {
        return uint.Parse(this.Next());
    }
    public long ReadLong()
    {
        return long.Parse(this.Next());
    }
    public double ReadDouble()
    {
        return double.Parse(this.Next());
    }
    public Tuple<int, int> ReadTup(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<long, long> ReadTupLong(int add = 0)
    {
        return Tuple.Create(this.ReadLong() + add, this.ReadLong() + add);
    }
    public Tuple<int, int, int> ReadTup3(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<int, int, int, int> ReadTup4(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public int[] ReadIntArray(int n)
    {
        var array = new int[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadInt();
        }
        return array;
    }
    public long[] ReadLongArray(int n)
    {
        var array = new long[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadLong();
        }
        return array;
    }
    public double[] ReadDoubleArray(int n)
    {
        var array = new double[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadDouble();
        }
        return array;
    }
    public char[] ReadCharArray(int n)
    {
        var array = new char[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadChar();
        }
        return array;
    }
    public string[] ReadStrArray(int n)
    {
        var array = new string[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadStr();
        }
        return array;
    }
    public Tuple<long, long>[] ReadTupLongArray(int n, int add = 0)
    {
        var array = new Tuple<long, long>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTupLong(add);
        }
        return array;
    }
    public Tuple<int, int>[] ReadTupArray(int n, int add = 0)
    {
        var array = new Tuple<int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup(add);
        }
        return array;
    }
    public Tuple<int, int, int>[] ReadTup3Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup3(add);
        }
        return array;
    }
    public Tuple<int, int, int, int>[] ReadTup4Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup4(add);
        }
        return array;
    }
}