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 Rust (1.42.0) (judge verdict: Wrong Answer)

trait BinarySearch<T> {
	#[allow(patterns_in_fns_without_body)]
	fn binary_search_by<F>(&self, mut f: F) -> Result<T, T>
	where
		F: FnMut(&T) -> std::cmp::Ordering;
}

impl<
		T: Sized
			+ PartialOrd
			+ std::ops::Add<Output = T>
			+ std::ops::Sub<Output = T>
			+ std::ops::Div<Output = T>
			+ Copy
			+ Clone
			+ From<u8>,
	> BinarySearch<T> for std::ops::Range<T>
{
	fn binary_search_by<F>(&self, mut f: F) -> Result<T, T>
	where
		F: FnMut(&T) -> std::cmp::Ordering,
	{
		use std::cmp::Ordering::*;
		if self.end <= self.start {
			return Err(T::from(0));
		}
		let mut base = self.start;
		let mut size = self.end - base;
		while size > T::from(1) {
			let half = size / T::from(2);
			let mid = base + half;
			let cmp = f(&mid);
			base = if cmp == Greater { base } else { mid };
			size = size - half;
		}
		let cmp = f(&base);
		if cmp == Equal {
			Ok(base)
		} else {
			Err(base + T::from((cmp == Less) as u8))
		}
	}
}

fn main() {
	let n: usize;
	let k: i64;
	let a: Vec<i64>;

	text_io::scan!("{} {}", n, k);
	a = (0..n).map(|_| text_io::read!()).collect();

	let max = *a.iter().max().unwrap();
	use std::cmp::Ordering::*;
	let ans = (0..max)
		.binary_search_by(|m| {
			println!("m={}", m);
			// if k >= a.iter().map(|a| (a + m - 1) / m - 1).sum() {
			if k as f64 >= a.iter().map(|a| *a as f64 / *m as f64).sum() {
				Greater
			} else {
				Less
			}
		})
		.err();
	println!("{}", ans.unwrap());
}