← Home
For problem statement at 1000-1999/1600-1699/1670-1679/1670/problemF.txt this is a correct solution, but verifier at 1000-1999/1600-1699/1670-1679/1670/verifierF.go ends with test 1 failed
input:
1 32 65 19
expected:1000000006
got:0

exit status 1 can you fix the verifier? package main

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

const MOD int64 = 1000000007
const MAXB = 64

func modPow(a, e int64) int64 {
	res := int64(1)
	for e > 0 {
		if e&1 == 1 {
			res = res * a % MOD
		}
		a = a * a % MOD
		e >>= 1
	}
	return res
}

func main() {
	in := bufio.NewReaderSize(os.Stdin, 1<<20)
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	var n int
	var l, r, z int64
	fmt.Fscan(in, &n, &l, &r, &z)

	fact := make([]int64, n+1)
	invFact := make([]int64, n+1)
	fact[0] = 1
	for i := 1; i <= n; i++ {
		fact[i] = fact[i-1] * int64(i) % MOD
	}
	invFact[n] = modPow(fact[n], MOD-2)
	for i := n; i >= 1; i-- {
		invFact[i-1] = invFact[i] * int64(i) % MOD
	}

	comb := make([]int64, n+1)
	for k := 0; k <= n; k++ {
		comb[k] = fact[n] * invFact[k] % MOD * invFact[n-k] % MOD
	}

	var parComb [2][]int64
	for k := 0; k <= n; k++ {
		parComb[k&1] = append(parComb[k&1], comb[k])
	}

	m := n + 2
	var start [4][]int
	for typ := 0; typ < 4; typ++ {
		rb := typ >> 1
		zb := typ & 1
		start[typ] = make([]int, m)
		for c := 0; c < m; c++ {
			b := rb ^ (c & 1) ^ zb
			start[typ][c] = (c + b - rb + zb) >> 1
		}
	}

	uz := uint64(z)

	countUpTo := func(R int64) int64 {
		if R < 0 {
			return 0
		}
		if uint64(R) < uz {
			return 0
		}
		dp := make([]int64, m)
		ndp := make([]int64, m)
		dp[0] = 1
		uR := uint64(R)

		for bit := 0; bit < MAXB; bit++ {
			rb := int((uR >> uint(bit)) & 1)
			zb := int((uz >> uint(bit)) & 1)
			typ := (rb << 1) | zb
			arr := parComb[zb]
			for i := 0; i < m; i++ {
				ndp[i] = 0
			}
			for c := 0; c < m; c++ {
				v := dp[c]
				if v == 0 {
					continue
				}
				s := start[typ][c]
				for i := 0; i < len(arr); i++ {
					cn := s + i
					x := ndp[cn] + v*arr[i]%MOD
					if x >= MOD {
						x -= MOD
					}
					ndp[cn] = x
				}
			}
			dp, ndp = ndp, dp
		}
		return dp[0]
	}

	ans := countUpTo(r) - countUpTo(l-1)
	if ans < 0 {
		ans += MOD
	}
	fmt.Fprintln(out, ans)
}