Problem:
Score : 300 points

Problem Statement

Hearing that energy drinks increase rating in those sites, Takahashi decides to buy up M cans of energy drinks.

There are N stores that sell energy drinks. In the i-th store, he can buy at most B_i cans of energy drinks for A_i yen (the currency of Japan) each.

What is the minimum amount of money with which he can buy M cans of energy drinks?

It is guaranteed that, in the given inputs, a sufficient amount of money can always buy M cans of energy drinks.

Constraints

All values in input are integers.

1 \leq N, M \leq 10^5

1 \leq A_i \leq 10^9

1 \leq B_i \leq 10^5

B_1 + ... + B_N \geq M

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
\vdots
A_N B_N

Output

Print the minimum amount of money with which Takahashi can buy M cans of energy drinks.

Sample Input 1

2 5
4 9
2 4

Sample Output 1

12

With 12 yen, we can buy one drink at the first store and four drinks at the second store, for the total of five drinks. However, we cannot buy 5 drinks with 11 yen or less.

Sample Input 2

4 30
6 18
2 5
3 10
7 9

Sample Output 2

130

Sample Input 3

1 100000
1000000000 100000

Sample Output 3

100000000000000

The output may not fit into a 32-bit integer type.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using static Input;

public class Prog
{
    private const int INF = 1000000007;
    private const long INFINITY = 9223372036854775807;
    public static void Main()
    {
        int N = NextInt();
        int M = NextInt();
        PriorityQueue<long, long[]> PQ = new PriorityQueue<long, long[]>();
        for (int i = 0; i < N; i++)
        {
            long a = NextLong();
            long b = NextLong();
            PQ.Enqueue(a, new long[2] { a, b });
        }
        long ans = 0;
        long take = 0;
        while (PQ.Count != 0)
        {
            if (take >= M) break;
            long[] ab = PQ.Dequeue();
            if (take + ab[1] >= M)
            {
                //差分買う
                ans += (M - take) * ab[0];
                take = M;
            }
            else
            {
                //全部買う
                take += ab[1];
                ans += ab[0] * ab[1];
            }
        }
        Console.WriteLine(ans);
    }
}


public class PriorityQueue<Tkey, Tvalue> where Tkey : IComparable
{
    private static List<Tkey> list = new List<Tkey>();
    private static List<Tvalue> value = new List<Tvalue>();
    public int Count { get; private set; } = 0;
    private static bool Descending;
    public PriorityQueue(bool b = true) { Descending = b; }
    private static int Compare(Tkey a, Tkey b)
    {
        if (Descending) return a.CompareTo(b);
        else return b.CompareTo(a);
    }
    public void Enqueue(Tkey e, Tvalue n)
    {
        Count++;
        int now = Count - 1;
        list.Add(e);
        value.Add(n);
        while (now != 0)
        {
            int par = (now - 1) / 2;
            if (Compare(list[par], e) <= 0) break;
            Tkey a = list[now]; list[now] = list[par]; list[par] = a;
            Tvalue b = value[now]; value[now] = value[par]; value[par] = b;
            now = par;
        }
    }
    public Tvalue Dequeue()
    {
        if (Count == 0) return (Tvalue)(object)(-1);
        Tvalue e = value.First();
        if (Count == 1) { list = new List<Tkey>(); value = new List<Tvalue>(); Count--; return e; }
        Tkey x = list[Count - 1];
        Tvalue y = value[Count - 1];
        int i = 0;
        while (i * 2 + 1 < Count)
        {
            int l = i * 2 + 1;
            int r = i * 2 + 2;
            if (r < Count && Compare(list[r], list[l]) < 0) l = r;
            if (Compare(list[l], x) >= 0) break;
            list[i] = list[l];
            value[i] = value[l];
            i = l;
        }
        list[i] = x;
        value[i] = y;
        Count--;
        return e;
    }
}

public class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
}