- Translate each rule into one explicit state update.
- Maintain the invariant after every processed item.
- Return the accumulated state once all relevant input has been handled.
Code notes
- 114 lines of Go from the credited upstream file 958F3.go.
- The implementation visibly relies on sequence storage.
- No explicit loop blocks detected.
Complexity
Count the number and nesting of passes over the input, then include the maintained containers in the memory estimate.
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 "math"8 "math/bits"9)10 1112type fft58 struct {13 n int14 omega, omegaInv []complex12815}16 17func newFFT58(n int) *fft58 {18 omega := make([]complex128, n)19 omegaInv := make([]complex128, n)20 for i := range omega {21 sin, cos := math.Sincos(2 * math.Pi * float64(i) / float64(n))22 omega[i] = complex(cos, sin)23 omegaInv[i] = complex(cos, -sin)24 }25 return &fft58{n, omega, omegaInv}26}27 28func (f *fft58) transform(a, omega []complex128) {29 for i, j := 0, 0; i < f.n; i++ {30 if i > j {31 a[i], a[j] = a[j], a[i]32 }33 for l := f.n >> 1; ; l >>= 1 {34 j ^= l35 if j >= l {36 break37 }38 }39 }40 for l := 2; l <= f.n; l <<= 1 {41 m := l >> 142 for st := 0; st < f.n; st += l {43 p := a[st:]44 for i := 0; i < m; i++ {45 t := omega[f.n/l*i] * p[m+i]46 p[m+i] = p[i] - t47 p[i] += t48 }49 }50 }51}52 53func (f *fft58) dft(a []complex128) {54 f.transform(a, f.omega)55}56 57func (f *fft58) idft(a []complex128) {58 f.transform(a, f.omegaInv)59 for i := range a {60 a[i] /= complex(float64(f.n), 0)61 }62}63 64func convolution58(a, b []int) []int {65 n, m := len(a), len(b)66 limit := 1 << uint(bits.Len(uint(n+m-1)))67 f := newFFT58(limit)68 cmplxA := make([]complex128, limit)69 for i, v := range a {70 cmplxA[i] = complex(float64(v), 0)71 }72 cmplxB := make([]complex128, limit)73 for i, v := range b {74 cmplxB[i] = complex(float64(v), 0)75 }76 f.dft(cmplxA)77 f.dft(cmplxB)78 for i := range cmplxA {79 cmplxA[i] *= cmplxB[i]80 }81 f.idft(cmplxA)82 conv := make([]int, n+m-1)83 for i := range conv {84 conv[i] = int(int64(math.Round(real(cmplxA[i]))) % 1009)85 }86 return conv87}88 89func convolutionN58(coefs [][]int) []int {90 n := len(coefs)91 if n == 1 {92 return coefs[0]93 }94 return convolution58(convolutionN58(coefs[:n/2]), convolutionN58(coefs[n/2:]))95}96 97func CF958F3(_r io.Reader, out io.Writer) {98 in := bufio.NewReader(_r)99 var n, m, k, x int100 Fscan(in, &n, &m, &k)101 coefs := make([][]int, m)102 for i := range coefs {103 coefs[i] = []int{1}104 }105 for ; n > 0; n-- {106 Fscan(in, &x)107 x--108 coefs[x] = append(coefs[x], 1)109 }110 Fprint(out, convolutionN58(coefs)[k])111}112 113114