← Home
```go
package main

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

func compare(b1, b2 []int) int {
	for i := 0; i < len(b1) && i < len(b2); i++ {
		if b1[i] != b2[i] {
			if b1[i] < b2[i] {
				return -1
			}
			return 1
		}
	}
	return 0
}

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

	P := make([]int, 0, n)
	for i := 0; i < n; i++ {
		if s[i] == '1' {
			P = append(P, i)
		}
	}
	c := len(P)

	pow2 := make([]int, n+1)
	pow2[0] = 1
	for i := 1; i <= n; i++ {
		pow2[i] = (pow2[i-1] * 2) % 1000000007
	}

	if k >= c {
		ans := 0
		for i := 0; i < c; i++ {
			ans = (ans + pow2[i]) % 1000000007
		}
		fmt.Println(ans)
		return
	}

	bestB := make([]int, c)
	avail := make([]int, n+1)
	candidateB := make([]int, c)

	// Option 1
	{
		S := k
		K := P[S:]
		availCount := 0
		kIdx := len(K) - 1
		for x := n - 1; x >= 0 && availCount < S; x-- {
			if kIdx >= 0 && x == K[kIdx] {
				kIdx--
			} else {
				avail[availCount] = x
				availCount++
			}
		}
		idx := 0
		iK, iA := len(K)-1, 0
		for iK >= 0 || iA < availCount {
			if iA == availCount || (iK >= 0 && K[iK] < avail[iA]) {
				bestB[idx] = n - 1 - K[iK]
				iK--
			} else {
				bestB[idx] = n - 1 - avail[iA]
				iA++
			}
			idx++
		}
	}

	// Option 2
	if k >= 1 && k-1 <= c-1 {
		S := k - 1
		minLen := n
		for i := 0; i <= S; i++ {
			if P[i+c-S-1]-P[i]+1 < minLen {
				minLen = P[i+c-S-1] - P[i] + 1
			}
		}
		Lstar := c
		if minLen > c {
			Lstar = minLen
		}

		for i := 0; i <= S; i++ {
			if P[i+c-S-1]-P[i]+1 <= Lstar {
				l := P[i]
				if n-Lstar < l {
					l = n - Lstar
				}

				maxVal := P[i+c-S-1] - l
				if maxVal > bestB[0] {
					continue
				}

				startIdx := sort.SearchInts(P, l)
				K := P[startIdx : startIdx+c-S]
				availCount := 0
				kIdx := 0
				for x := l; x <= l+Lstar-1 && availCount < S; x++ {
					if kIdx < len(K) && x == K[kIdx] {
						kIdx++
					} else {
						avail[availCount] = x
						availCount++
					}
				}

				idx := c - 1
				iK, iA := 0, 0
				for iK < len(K) || iA < availCount {
					if iA == availCount || (iK < len(K) && K[iK] < avail[iA]) {
						candidateB[idx] = K[iK] - l
						iK++
					} else {
						candidateB[idx] = avail[iA] - l
						iA++
					}
					idx--
				}

				if compare(candidateB, bestB) < 0 {
					copy(bestB, candidateB)
				}
			}
		}
	}

	// Option 3
	if k >= 2 && k-2 <= c-1 {
		S := k - 2
		minLen := n
		for i := 0; i <= S; i++ {
			if P[i+c-S-1]-P[i]+1 < minLen {
				minLen = P[i+c-S-1] - P[i] + 1
			}
		}
		Lstar := c
		if minLen > c {
			Lstar = minLen
		}

		for i := 0; i <= S; i++ {
			if P[i+c-S-1]-P[i]+1 <= Lstar {
				l := P[i+c-S-1] - Lstar + 1
				if l < 0 {
					l = 0
				}

				startIdx := sort.SearchInts(P, l)
				endIdx := sort.SearchInts(P, l+Lstar)
				Pin := P[startIdx:endIdx]
				K := Pin[len(Pin)-(c-S):]

				maxVal := Lstar - 1 - (K[0] - l)
				if maxVal > bestB[0] {
					continue
				}

				availCount := 0
				kIdx := len(K) - 1
				for x := l + Lstar - 1; x >= l && availCount < S; x-- {
					if kIdx >= 0 && x == K[kIdx] {
						kIdx--
					} else {
						avail[availCount] = x
						availCount++
					}
				}

				idx := c - 1
				iK, iA := len(K)-1, availCount-1
				for iK >= 0 || iA >= 0 {
					if iA < 0 || (iK >= 0 && K[iK] > avail[iA]) {
						candidateB[idx] = Lstar - 1 - (K[iK] - l)
						iK--
					} else {
						candidateB[idx] = Lstar - 1 - (avail[iA] - l)
						iA--
					}
					idx--
				}

				if compare(candidateB, bestB) < 0 {
					copy(bestB, candidateB)
				}
			}
		}
	}

	ans := 0
	for _, b := range bestB {
		ans = (ans + pow2[b]) % 1000000007
	}
	fmt.Println(ans)
}
```