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: Accepted)

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
			+ std::fmt::Display
			+ 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(self.start);
		}
		let mut base = self.start;
		let mut size = self.end - base;
		loop {
			let half = size / T::from(2);
			let mid = base + half;
			let cmp = f(&mid);
			match cmp {
				Less => base = mid,
				Equal => return Ok(mid),
				_ => {}
			}
			if size <= half || T::from(0) == half {
				return Err(base + T::from((cmp == Less) as u8));
			}
			size = size - half;
		}
	}
}

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();

	use std::cmp::Ordering::*;
	let ans = (0..1_000_000_001)
		.binary_search_by(|m| {
			if 1 == *m {
				return Equal;
			};
			if k >= a.iter().map(|a| (a + m - 1) / m - 1).sum() {
				Greater
			} else {
				Less
			}
		})
		.and_then(|q: i64| -> Result<i64, i64> { Err(q) })
		.err();
	println!("{}", ans.unwrap());
}