```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)
}
```