package main
import (
"bufio"
"container/heap"
"fmt"
"os"
)
// LongHeap implements heap.Interface and holds int64s.
// To match Kotlin's PriorityQueue<Long>() (which is a min-heap),
// we use a standard min-heap implementation.
type LongHeap []int64
func (h LongHeap) Len() int { return len(h) }
func (h LongHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h LongHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *LongHeap) Push(x interface{}) {
*h = append(*h, x.(int64))
}
func (h *LongHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func main() {
// Using fast I/O as fmt.Scan is slow for competitive programming
reader := bufio.NewReader(os.Stdin)
var n, k, x int
fmt.Fscan(reader, &n, &k, &x)
a := make([]int64, n)
for i := 0; i < n; i++ {
fmt.Fscan(reader, &a[i])
}
pq := &LongHeap{}
ok := func(mid int64) bool {
var sum int64 = 0
rem := 0
*pq = (*pq)[:0] // Fast way to clear the heap
heap.Init(pq)
for i := 0; i < n; i++ {
// In Kotlin: pq.add(-a[i]). Adding negative values to a min-heap
// makes it behave like a max-heap (extracting the largest original value).
heap.Push(pq, -a[i])
sum += a[i]
for sum > mid && pq.Len() > 0 {
// pq.Pop() returns the smallest (most negative) value
val := heap.Pop(pq).(int64)
sum += val // Adding a negative is subtraction
rem++
}
if rem > k {
return false
}
if pq.Len() == x {
sum = 0
*pq = (*pq)[:0]
heap.Init(pq)
}
}
return true
}
// Binary search logic
var lo int64 = -1
var hi int64 = 1
// Initial range finding
for !ok(hi) {
lo = hi
hi *= 2
}
// Refined binary search
for hi-lo > 1 {
mid := (lo + hi) / 2
if ok(mid) {
hi = mid
} else {
lo = mid
}
}
fmt.Println(hi)
}