Problem:
Score : 500 points

Problem Statement

We have N logs of lengths A_1,A_2,\cdots A_N.

We can cut these logs at most K times in total. When a log of length L is cut at a point whose distance from an end of the log is t (0<t<L), it becomes two logs of lengths t and L-t.

Find the shortest possible length of the longest log after at most K cuts, and print it after rounding up to an integer.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq K \leq 10^9

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
A_1 A_2 \cdots A_N

Output

Print an integer representing the answer.

Sample Input 1

2 3
7 9

Sample Output 1

4

First, we will cut the log of length 7 at a point whose distance from an end of the log is 3.5, resulting in two logs of length 3.5 each.

Next, we will cut the log of length 9 at a point whose distance from an end of the log is 3, resulting in two logs of length 3 and 6.

Lastly, we will cut the log of length 6 at a point whose distance from an end of the log is 3.3, resulting in two logs of length 3.3 and 2.7.

In this case, the longest length of a log will be 3.5, which is the shortest possible result. After rounding up to an integer, the output should be 4.

Sample Input 2

3 0
3 4 5

Sample Output 2

5

Sample Input 3

10 10
158260522 877914575 602436426 24979445 861648772 623690081 433933447 476190629 262703497 211047202

Sample Output 3

292638192

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace contest_Csharp
{
    class PriorityQueue<T> : IEnumerable<T> where T : IComparable<T>
    {
        private List<T> heap = new List<T>();
        private int lastindex = -1;
        private void swap(int n, int m)
        {
            T wait = heap[n];
            heap[n] = heap[m];
            heap[m] = wait;
        }
        public int Count()
        {
            return lastindex + 1;
        }
        public void Enqueue(T data)
        {
            int p;
            if (lastindex + 1 < heap.Count())
            {
                heap[lastindex + 1] = data;
            }
            else
            {
                heap.Add(data);
            }
            lastindex++;
            p = lastindex;

            while (true)
            {
                if (p > 0 && heap[p].CompareTo(heap[(p - 1) / 2]) <= -1)
                {
                    swap(p, (p - 1) / 2);
                    p = (p - 1) / 2;
                }
                else
                {
                    break;
                }
            }
        }
        public T Peek()
        {
            return heap[0];
        }
        public T Dequeue()
        {
            T result = Peek();
            heap[0] = default(T);
            swap(0, lastindex);
            lastindex--;
            int p = 0;
            while (true)
            {
                int np;
                if (2 * p + 1 > lastindex)
                {
                    break;
                }
                else
                {
                    np = ((2 * p + 1 == lastindex) || heap[2 * p + 1].CompareTo(heap[2 * p + 2]) <= -1)
                        ? (2 * p + 1) : (2 * p + 2);
                }
                if (heap[p].CompareTo(heap[np]) >= 1)
                {
                    swap(p, np);
                    p = np;
                }
                else
                {
                    break;
                }
            }

            return result;
        }
        public PriorityQueue<T> Clone()
        {
            var c = new PriorityQueue<T>();
            T[] ar = null;
            heap.ToArray().CopyTo(ar, 0);
            c.heap = ar.ToList();
            c.lastindex = lastindex;
            return c;
        }
        public IEnumerator<T> GetEnumerator()
        {
            PriorityQueue<T> copy = new PriorityQueue<T>();
            T[] carray = null;
            heap.ToArray().CopyTo(carray, 0);
            copy.heap = carray.ToList();
            copy.lastindex = lastindex;
            for (int i = 0; i < lastindex + 1; i++)
            {
                yield return copy.Dequeue();
            }

        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            PriorityQueue<T> copy = new PriorityQueue<T>();
            T[] carray = null;
            heap.ToArray().CopyTo(carray, 0);
            copy.heap = carray.ToList();
            copy.lastindex = lastindex;
            for (int i = 0; i < lastindex + 1; i++)
            {
                yield return copy.Dequeue();
            }
        }


    }
    class Program
    {
        public static (long m,long s)[,] dp;

        static void Main(string[] args)
        {
            checked
            {
                var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
                Console.SetOut(sw);

                var vals = Console.ReadLine().Split(' ').
                    Select(x => int.Parse(x)).ToList();

                var N = vals[0];
                var K = vals[1];
                var A= Console.ReadLine().Split(' ').
                    Select(x => int.Parse(x)).ToList();
                var Max = A.Max();
                var Inf = 0;

                while (Max-Inf>1)
                {
                    var md = (Max+Inf+1)/ 2 ;
                    var cnt = 0;
                    foreach(var a in A)
                    {
                        cnt += (a+md-1 )/ md -1;
                    }
                    if (cnt <= K)
                    {
                        Max = md;
                    }
                    else
                    {
                        Inf = md;
                    }
                }

                Console.WriteLine(Max);

                Console.Out.Flush();
            }




        }
    }
}