- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 87 lines of Go from the credited upstream file 1051E.go.
- The implementation visibly relies on sequence storage.
- No explicit loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1package main2 3import (4 "bufio"5 . "fmt"6 "io"7)8 910func calcZ51(s string) []int {11 n := len(s)12 z := make([]int, n)13 for i, l, r := 1, 0, 0; i < n; i++ {14 if i <= r {15 z[i] = min(z[i-l], r-i+1)16 }17 for i+z[i] < n && s[z[i]] == s[i+z[i]] {18 l, r = i, i+z[i]19 z[i]++20 }21 }22 z[0] = n23 return z24}25 26func cf1051E(_r io.Reader, out io.Writer) {27 in := bufio.NewReader(_r)28 const mod = 99824435329 var S, L, R string30 Fscan(in, &S, &L, &R)31 32 n, nl, nr := len(S), len(L), len(R)33 if nl > n {34 Fprint(out, 0)35 return36 }37 zl := calcZ51(L + S)38 zr := calcZ51(R + S)39 40 sum := make([]int, n+2)41 sum[1] = 142 pre := 043 for i := 1; i <= n; i++ {44 sum[i+1] = sum[i]45 if i < nl {46 pre = 047 continue48 }49 50 51 l, r := i-nr, i-nl52 if lcp := zl[nl+r]; lcp < nl && S[r+lcp] < L[lcp] {53 r--54 if r < 0 {55 pre = 056 continue57 }58 }59 if l < 0 {60 l = 061 } else {62 if lcp := zr[nr+l]; lcp < nr && S[l+lcp] > R[lcp] {63 l++64 }65 }66 if l > r {67 pre = 068 continue69 }70 71 f := 072 if L == "0" && S[i-1] == '0' {73 f = pre74 r--75 }76 f = (f + sum[r+1] - sum[l]) % mod77 pre = f78 if i < n && S[i] == '0' {79 f = 080 }81 sum[i+1] += f82 }83 Fprint(out, pre)84}85 8687