← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Substring struct {
	i, j int
}

const INF int64 = 2000000000000000000

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	var k int64
	fmt.Fscan(reader, &n, &m, &k)
	var s string
	fmt.Fscan(reader, &s)

	lcp := make([][]int, n+1)
	for i := range lcp {
		lcp[i] = make([]int, n+1)
	}
	for i := n - 1; i >= 0; i-- {
		for j := n - 1; j >= 0; j-- {
			if s[i] == s[j] {
				lcp[i][j] = 1 + lcp[i+1][j+1]
			} else {
				lcp[i][j] = 0
			}
		}
	}

	subs := make([]Substring, 0, n*(n+1)/2)
	for i := 0; i < n; i++ {
		for j := i; j < n; j++ {
			subs = append(subs, Substring{i, j})
		}
	}

	sort.Slice(subs, func(a, b int) bool {
		i1, j1 := subs[a].i, subs[a].j
		i2, j2 := subs[b].i, subs[b].j
		l := lcp[i1][i2]
		len1 := j1 - i1 + 1
		len2 := j2 - i2 + 1
		if l < len1 && l < len2 {
			return s[i1+l] < s[i2+l]
		}
		return len1 < len2
	})

	var U []Substring
	for i := 0; i < len(subs); i++ {
		if i == 0 {
			U = append(U, subs[i])
		} else {
			prev := U[len(U)-1]
			curr := subs[i]
			len1 := prev.j - prev.i + 1
			len2 := curr.j - curr.i + 1
			same := false
			if len1 == len2 && lcp[prev.i][curr.i] >= len1 {
				same = true
			}
			if !same {
				U = append(U, curr)
			}
		}
	}

	L := make([]int, n)
	dp := make([]int64, n+1)
	nextDp := make([]int64, n+1)
	sumDp := make([]int64, n+2)

	C := func(sub Substring) int64 {
		x := sub.i
		y := sub.j
		subLen := y - x + 1

		for i := 0; i < n; i++ {
			l := lcp[i][x]
			if l < subLen {
				if i+l < n && s[i+l] > s[x+l] {
					L[i] = l + 1
				} else {
					L[i] = n + 1 
				}
			} else {
				L[i] = subLen
			}
		}

		for i := 0; i <= n; i++ {
			dp[i] = 0
		}
		dp[n] = 1

		for j := 1; j <= m; j++ {
			sumDp[n+1] = 0
			for i := n; i >= 0; i-- {
				sumDp[i] = sumDp[i+1] + dp[i]
				if sumDp[i] > INF {
					sumDp[i] = INF
				}
			}

			for i := 0; i < n; i++ {
				if L[i] <= n-i {
					start := i + L[i]
					nextDp[i] = sumDp[start]
				} else {
					nextDp[i] = 0
				}
			}
			nextDp[n] = 0
			for i := 0; i <= n; i++ {
				dp[i] = nextDp[i]
			}
		}

		return dp[0]
	}

	low := 0
	high := len(U) - 1
	ans := 0

	for low <= high {
		mid := (low + high) / 2
		if C(U[mid]) >= k {
			ans = mid
			low = mid + 1
		} else {
			high = mid - 1
		}
	}

	res := U[ans]
	fmt.Println(s[res.i : res.j+1])
}
```