```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
// Use buffered I/O for performance
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
// Helper to read the next token
next := func() string {
scanner.Scan()
return scanner.Text()
}
// Helper to parse int64
parseInt64 := func(s string) int64 {
v, _ := strconv.ParseInt(s, 10, 64)
return v
}
// Read n, m, k
nStr := next()
if nStr == "" {
return
}
n, _ := strconv.Atoi(nStr)
m := parseInt64(next())
k := parseInt64(next())
// minVals[r] stores the minimum value of (S_j - k * floor(j/m))
// for indices j such that j % m == r.
// We use a large number for infinity.
// Max possible sum roughly 3e14, so 4e18 is safe.
const INF = 4000000000000000000
minVals := make([]int64, m)
for i := range minVals {
minVals[i] = INF
}
// Base case: j = 0 (empty prefix)
// S_0 = 0, floor(0/m) = 0 => value is 0
// 0 % m = 0
minVals[0] = 0
var ans int64 = 0
var currentS int64 = 0
// Iterate through the array elements
for i := 1; i <= n; i++ {
val := parseInt64(next())
currentS += val
// Calculate quotient and remainder for current index i
q := int64(i) / m
x := int(int64(i) % m)
// Calculate the term for the current index: S_i - k * floor(i/m)
term := currentS - k*q
// Calculate the maximum cost for subarrays ending at i
// Cost = (S_i - S_j) - k * ceil((i-j)/m)
// This transforms to: Term_i - Term_j - (k if i%m > j%m else 0)
for y := 0; y < int(m); y++ {
if minVals[y] == INF {
continue
}
candidate := term - minVals[y]
// If x > y, we need an extra block of k
// based on the ceiling arithmetic derived from ceil((i-j)/m)
if x > y {
candidate -= k
}
if candidate > ans {
ans = candidate
}
}
// Update minVals with the current index i acting as a start point j for future
if term < minVals[x] {
minVals[x] = term
}
}
fmt.Fprintln(writer, ans)
}
```