using
System;
using
System.Collections.Generic;
using
System.Linq;
namespace
minimizeMaxElement {
class
Program {
static
void
Main(
string
[] args)
{
List<
int
> arr =
new
List<
int
>{ 9 };
int
K;
arr =
new
List<
int
>{ 2, 4, 8, 2 };
K = 4;
Console.WriteLine(MinimizeMaxElement(arr, K));
}
static
int
MinimizeMaxElement(List<
int
> arr,
int
K)
{
PriorityQueue<
int
> pq =
new
PriorityQueue<
int
>(arr);
int
max_element = pq.Peek();
while
(K-- > 0) {
int
element = pq.Pop();
int
half = element / 2;
pq.Push(half);
pq.Push(element - half);
max_element = pq.Peek();
if
(max_element <= 1)
break
;
}
return
max_element;
}
}
public
class
PriorityQueue<T>
where
T : IComparable<T> {
List<T> data;
public
PriorityQueue() {
this
.data =
new
List<T>(); }
public
PriorityQueue(IEnumerable<T> collection)
{
this
.data =
new
List<T>(collection);
for
(
int
i = (data.Count / 2) - 1; i >= 0; i--)
HeapifyDown(i);
}
public
int
Count() {
return
data.Count; }
public
bool
IsEmpty() {
return
Count() == 0; }
public
T Peek()
{
if
(IsEmpty())
throw
new
Exception(
"Priority queue is empty."
);
return
data[0];
}
public
T Pop()
{
if
(IsEmpty())
throw
new
Exception(
"Priority queue is empty."
);
T element = Peek();
Swap(0, Count() - 1);
data.RemoveAt(Count() - 1);
HeapifyDown(0);
return
element;
}
public
void
Push(T item)
{
data.Add(item);
HeapifyUp(Count() - 1);
}
private
void
HeapifyUp(
int
index)
{
if
(index == 0)
return
;
int
parentIndex = (index - 1) / 2;
if
(data[index].CompareTo(data[parentIndex]) > 0) {
Swap(index, parentIndex);
HeapifyUp(parentIndex);
}
}
private
void
HeapifyDown(
int
index)
{
int
leftIndex = (2 * index) + 1;
int
rightIndex = (2 * index) + 2;
int
largestIndex = index;
if
(leftIndex < Count()
&& data[leftIndex].CompareTo(data[largestIndex])
> 0)
largestIndex = leftIndex;
if
(rightIndex < Count()
&& data[rightIndex].CompareTo(
data[largestIndex])
> 0)
largestIndex = rightIndex;
if
(largestIndex != index) {
Swap(index, largestIndex);
HeapifyDown(largestIndex);
}
}
private
void
Swap(
int
firstIndex,
int
secondIndex)
{
T temp = data[firstIndex];
data[firstIndex] = data[secondIndex];
data[secondIndex] = temp;
}
}
}