- 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
- 98 lines of Go from the credited upstream file 724D.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 "bytes"6 . "fmt"7 "io"8)9 10111213141516 1718func CF724D(_r io.Reader, _w io.Writer) {19 in := bufio.NewReader(_r)20 out := bufio.NewWriter(_w)21 defer out.Flush()22 23 var m int24 var s []byte25 Fscan(in, &m, &s)26 n := len(s)27 pos := [26][]int{}28 for i, b := range s {29 b -= 'a'30 pos[b] = append(pos[b], i)31 }32 var fa []int33 initFa := func(n int) {34 fa = make([]int, n+1)35 for i := range fa {36 fa[i] = i37 }38 }39 var find func(int) int40 find = func(x int) int {41 if fa[x] != x {42 fa[x] = find(fa[x])43 }44 return fa[x]45 }46 mergeRange := func(l, r int) (merged bool) {47 if l < 0 {48 l = 049 }50 for i := find(l); i < r; i = find(i + 1) {51 fa[i] = r52 merged = true53 }54 return55 }56 57 initFa(n)58 ans := make([]byte, 0, n)59outer:60 for i, ps := range pos {61 b := byte(i + 'a')62 left := len(ps)63 for j := 0; j < len(ps); j++ {64 check := find(0)65 found := false66 for ; j < len(ps); j++ {67 if ps[j]-m+1 > check {68 break69 }70 found = true71 }72 if !found {73 for _, p := range ps[j:] {74 mergeRange(p-m+1, p+1)75 }76 break77 }78 if j > 0 {79 j--80 }81 p := ps[j]82 if mergeRange(p-m+1, p+1) {83 ans = append(ans, b)84 left--85 if find(0) >= n-m+1 {86 break outer87 }88 }89 }90 ans = append(ans, bytes.Repeat([]byte{b}, left)...)91 }92 Fprint(out, string(ans))93}94 95969798