```go
package main
import (
"bufio"
"container/heap"
"fmt"
"os"
"sort"
)
type Fenwick struct {
n int
tree []int64
}
func NewFenwick(n int) *Fenwick {
return &Fenwick{n: n, tree: make([]int64, n+2)}
}
func (f *Fenwick) Add(idx int, val int64) {
for idx <= f.n {
f.tree[idx] += val
idx += idx & -idx
}
}
func (f *Fenwick) Sum(idx int) int64 {
var res int64 = 0
for idx > 0 {
res += f.tree[idx]
idx -= idx & -idx
}
return res
}
type IntMaxHeap []int64
func (h IntMaxHeap) Len() int { return len(h) }
func (h IntMaxHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h IntMaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntMaxHeap) Push(x interface{}) {
*h = append(*h, x.(int64))
}
func (h *IntMaxHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func solve() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var n, k, x int
fmt.Fscan(reader, &n, &k, &x)
a := make([]int64, n)
var total int64 = 0
for i := 0; i < n; i++ {
fmt.Fscan(reader, &a[i])
total += a[i]
}
if k >= n {
fmt.Fprintln(writer, 0)
return
}
vals := make([]int64, n)
copy(vals, a)
sort.Slice(vals, func(i, j int) bool { return vals[i] < vals[j] })
uniq := make([]int64, 0, n)
for _, v := range vals {
if len(uniq) == 0 || uniq[len(uniq)-1] != v {
uniq = append(uniq, v)
}
}
m := len(uniq)
getIdx := func(val int64) int {
return sort.Search(len(uniq), func(i int) bool { return uniq[i] >= val }) + 1
}
check := func(M int64) bool {
if x == 1 {
cnt := 0
for _, v := range a {
if v > M {
cnt++
}
}
return cnt <= k
}
dp := make([]int, n)
prefixMax := make([]int, n)
for i := 0; i < n; i++ {
dp[i] = -1
}
bitCnt := NewFenwick(m)
bitSum := NewFenwick(m)
getKSum := func(k int) int64 {
if k <= 0 {
return 0
}
lo, hi := 1, m
pos := m
for lo <= hi {
mid := (lo + hi) / 2
if bitCnt.Sum(mid) >= int64(k) {
pos = mid
hi = mid - 1
} else {
lo = mid + 1
}
}
cntBefore := bitCnt.Sum(pos - 1)
sumBefore := bitSum.Sum(pos - 1)
need := int64(k) - cntBefore
return sumBefore + need*uniq[pos-1]
}
left := 0
for i := 0; i < n; i++ {
if i > 0 {
idx := getIdx(a[i-1])
bitCnt.Add(idx, 1)
bitSum.Add(idx, a[i-1])
}
for left <= i-1 {
sz := i - left
if sz < x-1 {
break
}
sumSmall := getKSum(x - 1)
if sumSmall <= M-a[i] {
break
}
idx := getIdx(a[left])
bitCnt.Add(idx, -1)
bitSum.Add(idx, -a[left])
left++
}
sz := i - left
if sz >= x-1 {
sumSmall := getKSum(x - 1)
if sumSmall <= M-a[i] {
bestPrev := 0
if left > 0 {
bestPrev = prefixMax[left-1]
}
if bestPrev >= 0 {
dp[i] = bestPrev + x
}
}
}
prefixMax[i] = dp[i]
if i > 0 && prefixMax[i-1] > prefixMax[i] {
prefixMax[i] = prefixMax[i-1]
}
}
suffix := make([]int, n+1)
suffix[n] = 0
h := &IntMaxHeap{}
heap.Init(h)
var sum int64 = 0
for i := n - 1; i >= 0; i-- {
heap.Push(h, a[i])
sum += a[i]
for sum > M && h.Len() > 0 {
val := heap.Pop(h).(int64)
sum -= val
}
for h.Len() > x-1 {
val := heap.Pop(h).(int64)
sum -= val
}
suffix[i] = h.Len()
}
if suffix[0] >= n-k {
return true
}
for i := 0; i < n; i++ {
if dp[i] >= 0 {
totalKept := dp[i] + suffix[i+1]
if totalKept >= n-k {
return true
}
}
}
return false
}
lo, hi := int64(0), total
for lo < hi {
mid := (lo + hi) / 2
if check(mid) {
hi = mid
} else {
lo = mid + 1
}
}
fmt.Fprintln(writer, lo)
}
func main() {
solve()
}
```