using
System;
using
System.Collections.Generic;
class
MaxDiff
{
static
int
MaximizeDifference(
int
n,
int
[] arr)
{
int
ans =
int
.MinValue;
int
[] prefix =
new
int
[3 * n];
int
[] suffix =
new
int
[3 * n];
int
sumVal = 0;
MinHeap<
int
> pq =
new
MinHeap<
int
>();
for
(
int
i = 0; i < 3 * n; i++)
{
pq.Add(arr[i]);
sumVal += arr[i];
if
(pq.Count > n)
{
int
val = pq.Remove();
sumVal -= val;
}
prefix[i] = sumVal;
}
sumVal = 0;
MaxHeap<
int
> pq2 =
new
MaxHeap<
int
>();
for
(
int
i = 3 * n - 1; i >= 0; i--)
{
pq2.Add(arr[i]);
sumVal += arr[i];
if
(pq2.Count > n)
{
int
val = pq2.Remove();
sumVal -= val;
}
suffix[i] = sumVal;
}
for
(
int
i = n; i <= 2 * n; i++)
{
ans = Math.Max(ans, prefix[i - 1] - suffix[i]);
}
return
ans;
}
static
void
Main()
{
int
n = 2;
int
[] arr = { 2, 3, 4, 2, 1, 4 };
Console.WriteLine(MaximizeDifference(n, arr));
}
}
class
MinHeap<T>
where
T : IComparable<T>
{
private
List<T> heap =
new
List<T>();
public
int
Count => heap.Count;
public
void
Add(T item)
{
heap.Add(item);
int
childIndex = heap.Count - 1;
while
(childIndex > 0)
{
int
parentIndex = (childIndex - 1) / 2;
if
(heap[childIndex].CompareTo(heap[parentIndex]) >= 0)
break
;
Swap(childIndex, parentIndex);
childIndex = parentIndex;
}
}
public
T Remove()
{
if
(heap.Count == 0)
throw
new
InvalidOperationException(
"Heap is empty."
);
T root = heap[0];
heap[0] = heap[heap.Count - 1];
heap.RemoveAt(heap.Count - 1);
int
currentIndex = 0;
while
(
true
)
{
int
leftChildIndex = 2 * currentIndex + 1;
int
rightChildIndex = 2 * currentIndex + 2;
int
smallestChildIndex = currentIndex;
if
(leftChildIndex < heap.Count && heap[leftChildIndex].CompareTo(heap[smallestChildIndex]) < 0)
smallestChildIndex = leftChildIndex;
if
(rightChildIndex < heap.Count && heap[rightChildIndex].CompareTo(heap[smallestChildIndex]) < 0)
smallestChildIndex = rightChildIndex;
if
(smallestChildIndex == currentIndex)
break
;
Swap(currentIndex, smallestChildIndex);
currentIndex = smallestChildIndex;
}
return
root;
}
private
void
Swap(
int
index1,
int
index2)
{
T temp = heap[index1];
heap[index1] = heap[index2];
heap[index2] = temp;
}
}
class
MaxHeap<T>
where
T : IComparable<T>
{
private
List<T> heap =
new
List<T>();
public
int
Count => heap.Count;
public
void
Add(T item)
{
heap.Add(item);
int
childIndex = heap.Count - 1;
while
(childIndex > 0)
{
int
parentIndex = (childIndex - 1) / 2;
if
(heap[childIndex].CompareTo(heap[parentIndex]) <= 0)
break
;
Swap(childIndex, parentIndex);
childIndex = parentIndex;
}
}
public
T Remove()
{
if
(heap.Count == 0)
throw
new
InvalidOperationException(
"Heap is empty."
);
T root = heap[0];
heap[0] = heap[heap.Count - 1];
heap.RemoveAt(heap.Count - 1);
int
currentIndex = 0;
while
(
true
)
{
int
leftChildIndex = 2 * currentIndex + 1;
int
rightChildIndex = 2 * currentIndex + 2;
int
largestChildIndex = currentIndex;
if
(leftChildIndex < heap.Count && heap[leftChildIndex].CompareTo(heap[largestChildIndex]) > 0)
largestChildIndex = leftChildIndex;
if
(rightChildIndex < heap.Count && heap[rightChildIndex].CompareTo(heap[largestChildIndex]) > 0)
largestChildIndex = rightChildIndex;
if
(largestChildIndex == currentIndex)
break
;
Swap(currentIndex, largestChildIndex);
currentIndex = largestChildIndex;
}
return
root;
}
private
void
Swap(
int
index1,
int
index2)
{
T temp = heap[index1];
heap[index1] = heap[index2];
heap[index2] = temp;
}
}