← Home
For problem statement at 1000-1999/1100-1199/1170-1179/1174/problemE.txt this is a correct solution, but verifier at 1000-1999/1100-1199/1170-1179/1174/verifierE.go ends with test 1 failed
expected: 635568961
got: 936569886
exit status 1 can you fix the verifier? package main

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

const MOD int64 = 1000000007

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 modInv(a int64) int64 {
	return modPow(a%MOD, MOD-2)
}

func main() {
	in := bufio.NewReader(os.Stdin)
	var n int64
	if _, err := fmt.Fscan(in, &n); err != nil {
		return
	}

	// k = floor(log2 n)
	k := 0
	for (int64(1)<<(k+1)) <= n {
		k++
	}

	// factorials up to n-1
	fact := make([]int64, n+1)
	fact[0] = 1
	for i := int64(1); i <= n; i++ {
		fact[i] = (fact[i-1] * i) % MOD
	}
	factNm1 := fact[n-1]

	// pow2 up to k
	pow2 := make([]int64, k+2)
	pow2[0] = 1
	for i := 1; i <= k+1; i++ {
		pow2[i] = pow2[i-1] << 1
	}

	// cnt[t] = count of numbers with v2 = t for t=0..k
	cnt := make([]int64, k+1)
	for t := 0; t < k; t++ {
		cnt[t] = n/(pow2[t]) - n/(pow2[t+1])
	}
	cnt[k] = n / pow2[k]

	// S[s] = sum_{t=0..s} cnt[t]
	S := make([]int64, k+1)
	var acc int64 = 0
	for s := 0; s <= k; s++ {
		acc += cnt[s]
		S[s] = acc
	}

	// Contribution for starting m = 2^k
	prod2 := int64(1)
	for a := 1; a <= k; a++ {
		num := cnt[a-1] % MOD
		den := S[a-1] % MOD
		prod2 = prod2 * num % MOD
		prod2 = prod2 * modInv(den) % MOD
	}
	ans := prod2 * factNm1 % MOD

	// Contribution for starting m = 3 * 2^{k-1}, if exists
	if k >= 1 {
		mExists := n >= 3*pow2[k-1]
		if mExists {
			// cA[t]: v2=t and divisible by 3
			// cB[t]: v2=t and not divisible by 3
			cA := make([]int64, k+1)
			cB := make([]int64, k+1)
			for t := 0; t <= k; t++ {
				x := n / (3 * pow2[t])
				y := n / (3 * (pow2[t] << 1))
				cA[t] = x - y
			}
			// exclude starting m = 3*2^{k-1}
			cA[k-1]--

			for t := 0; t <= k; t++ {
				cB[t] = cnt[t] - cA[t]
			}

			// sumBge[a] = sum_{t=a..k} cB[t]
			sumBge := make([]int64, k+2)
			for t := k; t >= 0; t-- {
				sumBge[t] = sumBge[t+1] + cB[t]
			}

			// P0[a] = success prob from state (a, flag=0)
			P0 := make([]int64, k)
			P0[0] = 1
			for a := 1; a <= k-1; a++ {
				num := (cA[a-1] % MOD + MOD) % MOD
				den := S[a-1] % MOD
				P0[a] = P0[a-1] * num % MOD * modInv(den) % MOD
			}

			// P1[a] = success prob from state (a, flag=1)
			P1 := make([]int64, k)
			P1[0] = 1
			for a := 1; a <= k-1; a++ {
				X2 := cA[a-1]
				X3 := sumBge[a]
				var Z int64
				if a >= 2 {
					Z += S[a-2]
				}
				Z += cB[a-1]
				den := ((X2 + X3 + Z) % MOD + MOD) % MOD
				part2 := (X2%MOD + MOD) % MOD * modInv(den) % MOD * P1[a-1] % MOD
				part3 := (X3%MOD + MOD) % MOD * modInv(den) % MOD * P0[a] % MOD
				P1[a] = (part2 + part3) % MOD
			}

			ans = (ans + P1[k-1]*factNm1) % MOD
		}
	}

	if ans < 0 {
		ans += MOD
	}
	fmt.Println(ans % MOD)
}