Problem:
Score : 400 points

Problem Statement

Takahashi is going to buy N items one by one.

The price of the i-th item he buys is A_i yen (the currency of Japan).

He has M discount tickets, and he can use any number of them when buying an item.

If Y tickets are used when buying an item priced X yen, he can get the item for \frac{X}{2^Y} (rounded down to the nearest integer) yen.

What is the minimum amount of money required to buy all the items?

Constraints

All values in input are integers.

1 \leq N, M \leq 10^5

1 \leq A_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N M
A_1 A_2 ... A_N

Output

Print the minimum amount of money required to buy all the items.

Sample Input 1

3 3
2 13 8

Sample Output 1

9

We can buy all the items for 9 yen, as follows:

Buy the 1-st item for 2 yen without tickets.

Buy the 2-nd item for 3 yen with 2 tickets.

Buy the 3-rd item for 4 yen with 1 ticket.

Sample Input 2

4 4
1 9 3 5

Sample Output 2

6

Sample Input 3

1 100000
1000000000

Sample Output 3

0

We can buy the item priced 1000000000 yen for 0 yen with 100000 tickets.

Sample Input 4

10 1
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000

Sample Output 4

9500000000

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Runtime.CompilerServices;
using static System.Console;
using static System.Math;

namespace AtCodeeeer
{
    class AtCOOOOOOOOOOOder
    {
        static void Main(string[] args)
        {
            long[] s = ReadLine().Split(' ').Select(long.Parse).ToArray();
            long n = s[0];
            long m = s[1];
            long[] Ai = ReadLine().Split(' ').Select(long.Parse).ToArray();

            var q = new PriorityQueue<long>(true);
            for (int i = 0; i < n; i++)
            {
                q.Push(Ai[i]);
            }

            while (m > 0)
            {
                long tmp = q.Pop();
                tmp /= 2;
                q.Push(tmp);
                m--;
            }

            long ans = 0;
            for (int i = 0; i < n; i++)
            {
                ans += q.Pop();
            }
            WriteLine(ans);
        }
        /// <summary>
        /// 優先度付きキュー を表す。
        /// System.Runtime.CompilerServicesが必要
        /// </summary>
        /// <typeparam name="T">キューの型</typeparam>
        public class PriorityQueue<T> where T : IComparable<T>
        {
            public bool Any() => Count > 0;
            public int Count { get; private set; }
            private bool Descendance;
            private T[] data = new T[65536];

            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            public PriorityQueue(bool descendance = false)
            {
                Descendance = descendance;
            }

            /// <summary>
            /// キューの最小 (<see cref="Descendance"/> が <see cref="true"/> の場合は最大) の要素を取得します。
            /// </summary>
            public T Top
            {
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
                get
                {
                    ValidateNonEmpty();
                    return data[1];
                }
            }

            /// <summary>
            /// キューの最小 (<see cref="Descendance"/> が <see cref="true"/> の場合は最大) の要素を削除して返す。
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            public T Pop()
            {
                var top = Top;
                var elem = data[Count--];
                int index = 1;
                while (true)
                {
                    if ((index << 1) >= Count)
                    {
                        if (index << 1 > Count) break;
                        if (elem.CompareTo(data[index << 1]) > 0 ^ Descendance) data[index] = data[index <<= 1];
                        else break;
                    }
                    else
                    {
                        var nextIndex = data[index << 1].CompareTo(data[(index << 1) + 1]) <= 0 ^ Descendance
                            ? (index << 1)
                            : (index << 1) + 1;
                        if (elem.CompareTo(data[nextIndex]) > 0 ^ Descendance) data[index] = data[index = nextIndex];
                        else break;
                    }
                }

                data[index] = elem;
                return top;
            }

            /// <summary>
            /// キューに要素を追加する。
            /// </summary>
            /// <param name="value">追加する要素</param>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            public void Push(T value)
            {
                int index = ++Count;
                if (data.Length == Count) Extend(data.Length * 2);
                while ((index >> 1) != 0)
                {
                    if (data[index >> 1].CompareTo(value) > 0 ^ Descendance) data[index] = data[index >>= 1];
                    else break;
                }

                data[index] = value;
            }

            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            private void Extend(int newSize)
            {
                T[] newDatas = new T[newSize];
                data.CopyTo(newDatas, 0);
                data = newDatas;
            }

            private void ValidateNonEmpty()
            {
                if (Count == 0) throw new Exception();
            }
        }
    }



}