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# (.NET Core 3.1.201) (judge verdict: Accepted)

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 Treap<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.Length - y;
            ans += res - 1;
            t.Erase(x);
        }
        Console.WriteLine(ans);
    }
    // AC: https://atcoder.jp/contests/arc033/tasks/arc033_3
    //     
    class Treap<T> : IEnumerable<T> where T : IComparable
    {
        public int Length
        {
            get { return this.Root == null ? 0 : this.NodeCount(this.Root); }
        }
        public T this[int i]
        {
            get
            {
                if (this.Root.Count < i - 1) throw new IndexOutOfRangeException();
                return this.Root.Get(i);
            }
        }
        public Node Root;
        private IComparer<T> Cmp = Comparer<T>.Default;
        public Treap(IComparer<T> cmp = null)
        {
            if (cmp != null) this.Cmp = cmp;
        }
        public Node Merge(Node l, Node r)
        {
            if (l == null || r == null) return l == null ? r : l;

            if (l.Priority > r.Priority)
            {
                l.R = this.Merge(l.R, r);
                return this.Update(l);
            }
            else
            {
                r.L = this.Merge(l, r.L);
                return this.Update(r);
            }
        }
        // 左にk個、右に残り(n-k)個に分割する
        public (Node, Node) Split(int k) { return this.Split(this.Root, k); }
        public (Node, Node) Split(Node t, int k)
        {
            if (t == null) return (null, null);
            if (k <= this.NodeCount(t.L))
            {
                var s = this.Split(t.L, k);
                t.L = s.Item2;
                return (s.Item1, this.Update(t));
            }
            else
            {
                var s = this.Split(t.R, k - this.NodeCount(t.L) - 1);
                t.R = s.Item1;
                return (this.Update(t), s.Item2);
            }
        }
        public int NodeCount(Node node)
        {
            return node == null ? 0 : node.Count;
        }
        public int LowerBouond(T value) { return this.LowerBouond(this.Root, value); }
        public int LowerBouond(Node node, T value)
        {
            if (node == null) return 0;
            if (this.Cmp.Compare(value, node.Value) <= 0)
                return this.LowerBouond(node.L, value);
            else
                return this.NodeCount(node.L) + 1 + this.LowerBouond(node.R, value);
        }
        public int UpperBound(T value) { return this.UpperBound(this.Root, value); }
        public int UpperBound(Node node, T value)
        {
            if (node == null) return 0;
            if (this.Cmp.Compare(value, node.Value) >= 0)
                return this.NodeCount(node.L) + 1 + this.UpperBound(node.R, value);
            else
                return this.UpperBound(node.L, value);
        }
        public int ValueCount(T value)
        {
            return this.UpperBound(value) - this.LowerBouond(value);
        }
        public void Insert(T value)
        {
            var sub = this.Split(this.Root, this.LowerBouond(value));
            var newNode = new Node(value);
            var merged = this.Merge(sub.Item1, newNode);
            this.Root = this.Merge(merged, sub.Item2);
        }
        public void Erase(T value)
        {
            if (this.ValueCount(value) == 0) return;
            var sub = this.Split(this.Root, this.LowerBouond(value));
            this.Root = this.Merge(sub.Item1, this.Split(sub.Item2, 1).Item2);
        }
        // 書き換え
        public void InsertAt(Node node, int k)
        {
            var sub = this.Split(this.Root, k);
            var merged = this.Merge(sub.Item1, node);
            this.Root = this.Merge(merged, sub.Item2);
        }
        public void InsertAt(T value, int k)
        {
            var node = new Node(value);
            var sub = this.Split(this.Root, k);
            var merged = this.Merge(sub.Item1, node);
            this.Root = this.Merge(merged, sub.Item2);
        }
        public Node EraseAt(int k)
        {
            var sub = this.Split(this.Root, k);
            var sub2 = this.Split(sub.Item2, 1);
            var res = sub2.Item1;
            this.Root = this.Merge(sub.Item1, sub2.Item2);
            return res;
        }
        public Node Update(Node node)
        {
            node.Count = this.NodeCount(node.L) + this.NodeCount(node.R) + 1;
            // RMQ
            var acc = node.Value;
            if (node.L != null && acc.CompareTo(node.L.Min) > 0) acc = node.L.Min;
            if (node.R != null && acc.CompareTo(node.R.Min) > 0) acc = node.R.Min;
            node.Min = acc;
            return node;
        }
        public T RangeQuery(int l, int r)
        {
            // [l, r)
            // 0-(l-1), l-(r-1), r-N の部分木に分割する
            var tmp = this.Split(this.Root, r);
            var rroot = tmp.Item2;
            tmp = this.Split(tmp.Item1, l);
            var lroot = tmp.Item1;
            var croot = tmp.Item2;
            var ans = croot.Min;
            this.Root = this.Merge(this.Merge(lroot, croot), rroot);
            return ans;
        }
        public void UpdateValue(int k, T value)
        {
            this.EraseAt(k);
            var newNode = new Node(value);
            this.InsertAt(newNode, k);
        }
        public void Shift(int l, int r)
        {
            // [l, r) の区間をシフト
            var node = EraseAt(r - 1);
            this.InsertAt(node, l);
        }
        public class Node
        {
            private static Random Rand = new Random();
            public T Value;
            public Node L = null;
            public Node R = null;
            public int Count;
            public double Priority;
            public T Min;
            public Node(T value, double priority)
            {
                this.Value = value;
                this.Priority = priority;
                this.Count = 1;
                //
                this.Min = value;
            }
            public Node(T value) : this(value, Rand.NextDouble()) { }
            public T Get(int i) { return this.GetNode(i).Value; }
            public Node GetNode(int i)
            {
                var lcount = 0;
                if (this.L != null) lcount = this.L.Count;
                if (lcount == i) return this;
                else if (lcount < i) return this.R.GetNode(i - lcount - 1);
                else return this.L.GetNode(i);
            }
        }
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < this.Length; i++) yield return this.Root.Get(i);
        }
        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;
    }
}