← Home
For problem statement at 0-999/900-999/990-999/992/problemD.txt this is a correct solution, but verifier at 0-999/900-999/990-999/992/verifierD.go ends with All tests passed can you fix the verifier? ```go
package main

import (
	"bufio"
	"fmt"
	"math/big"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	var n, k int
	fmt.Fscan(reader, &n, &k)

	a := make([]int64, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &a[i])
	}

	// For a subsegment [l, r]:
	// product / sum = k
	// product = k * sum
	// 
	// Since elements can be up to 1e8 and n up to 2e5, products can be astronomically large.
	// We need to handle big numbers.
	//
	// Key insight: if all elements are >= 2, the product grows exponentially.
	// Specifically, if there are m elements all >= 2, product >= 2^m.
	// Sum <= m * 1e8.
	// For product/sum = k <= 1e5:
	// 2^m / (m * 1e8) <= k <= 1e5
	// 2^m <= m * 1e13
	// For m = 60: 2^60 ~ 1.15e18, m*1e13 = 6e14, so 2^60 > 60*1e13
	// For m = 50: 2^50 ~ 1.1e15, 50*1e13 = 5e14, so 2^50 > 50*1e13
	// For m = 44: 2^44 ~ 1.76e13, 44*1e13 = 4.4e14 - still 2^44 < 44*1e13... wait
	// Actually let me recheck: we need product = k * sum
	// product >= 2^m, k*sum <= k * m * 1e8 = 1e5 * m * 1e8 = m * 1e13
	// So if 2^m > m * 1e13, no solution possible.
	// 2^44 = 17592186044416 ~ 1.76e13, 44 * 1e13 = 4.4e14 -> 2^44 < 44*1e13
	// 2^50 = 1125899906842624 ~ 1.1e15, 50*1e13 = 5e14 -> 2^50 > 50*1e13
	// So around m=47 or so it crosses. Let's use threshold of 60 to be safe.
	//
	// Strategy: For each right endpoint r, maintain a window.
	// The number of elements > 1 in the window can be at most ~60.
	// So for each r, we only need to check subsegments starting from the last ~60 non-one elements.

	count := int64(0)
	bigK := big.NewInt(int64(k))

	// positions of elements > 1, stored as we go
	// For each r, we look at windows [l, r]
	// We use the fact that if there are more than 60 elements > 1, product/sum > k for any k <= 1e5

	ones := make([]int, 0) // not needed in this approach

	_ = ones

	// For each r, find the leftmost l such that the subsegment [l,r] could satisfy the condition
	// Elements equal to 1 don't change product but add to sum.
	// 
	// We iterate r from 0 to n-1.
	// We keep track of positions where a[i] > 1.
	// For fixed r, we only need to consider at most 60 starting positions:
	// the ones that include at most 60 elements > 1.

	nonOnePositions := []int{} // positions with value > 1, in order

	for r := 0; r < n; r++ {
		if a[r] > 1 {
			nonOnePositions = append(nonOnePositions, r)
		}

		// We need to consider windows [l, r] where number of elements > 1 <= 60
		// The leftmost such l: if len(nonOnePositions) > 60, start from nonOnePositions[len-60-1]+1
		
		maxNonOne := 60
		startIdx := 0
		if len(nonOnePositions) > maxNonOne {
			startIdx = nonOnePositions[len(nonOnePositions)-maxNonOne-1] + 1
		}

		// Now iterate over possible starting positions
		// For efficiency, iterate over groups: for each subset of non-one elements in window
		// We'll iterate l from startIdx to r
		
		// But that could still be O(n) per r. We need smarter approach.
		// Key: product changes only at positions with value > 1.
		// Between consecutive non-one positions, sum changes linearly (adding 1s).
		
		// Let's iterate over subsets of non-one elements (at most 60 of them in window)
		// For each choice of leftmost non-one element included, we have a range of valid l's.
		
		// nonOnePositions relevant: last min(60, len) positions
		start := 0
		if len(nonOnePositions) > maxNonOne {
			start = len(nonOnePositions) - maxNonOne
		}
		
		relevantNonOne := nonOnePositions[start:]
		
		// For each subset of non-one positions (by choosing how many from the right to include):
		// If we include j non-one elements (the last j in relevantNonOne),
		// l ranges from (j==len(relevantNonOne) ? startIdx : relevantNonOne[len(relevantNonOne)-j-1]+1) to relevantNonOne[len(relevantNonOne)-j]-1... 
		// This is getting complex. Let me just iterate over the at most 60 non-one boundaries.
		
		// For each j from 0 to len(relevantNonOne):
		// j non-one elements are included (the rightmost j)
		// l can range from lMin to lMax
		// product is fixed for this j
		// sum = product_of_non_ones * (r - l + 1 - count_of_non_ones_in_window + sum_of_non_ones... 
		// Actually sum = sum of all elements in [l, r]
		
		// Let me compute prefix sums for sum computation.
		// This approach: for each r, check at most 60 "breakpoints" for l.
		
		// I'll just do it simply with big.Int for the ~60 cases per r.
		
		// For each starting position of a non-one element (or startIdx), compute product and sum.
		
		// Collect candidate l values: startIdx and each position in relevantNonOne
		
		_ = startIdx
		
		// Build candidates for l
		candidates := []int{}
		candidates = append(candidates, startIdx)
		for _, pos := range relevantNonOne {
			candidates = append(candidates, pos)
		}
		
		// For each pair of consecutive candidates (l ranges)
		// Within a range, product is fixed, sum varies linearly
		// product = k * sum => sum = product / k (must be integer)
		// sum = prefixSum[r+1] - prefixSum[l]
		// So prefixSum[l] = prefixSum[r+1] - product/k
		// l is determined uniquely!
		
		// So for each "segment" of l values with the same product,
		// check if the required l is in that segment.
		
		_ = count
		_ = bigK
		_ = candidates
		
		// Let me restart with a cleaner implementation below
		count = count // placeholder
	}
	
	// Clean implementation
	count = solve(n, k, a)
	fmt.Println(count)
}

func solve(n, k int, a []int64) int64 {
	// Prefix sums
	prefix := make([]int64, n+1)
	for i := 0; i < n; i++ {
		prefix[i+1] = prefix[i] + a[i]
	}

	sumRange := func(l, r int) int64 {
		return prefix[r+1] - prefix[l]
	}

	count := int64(0)
	bigK := big.NewInt(int64(k))

	nonOnePositions := []int{}
	maxNonOne := 60

	for r := 0; r < n; r++ {
		if a[r] > 1 {
			nonOnePositions = append(nonOnePositions, r)
		}

		// relevant non-one positions: last maxNonOne
		startNonOne := 0
		if len(nonOnePositions) > maxNonOne {
			startNonOne = len(nonOnePositions) - maxNonOne
		}
		relevantNonOne := nonOnePositions[startNonOne:]

		// startIdx: minimum l we consider
		startIdx := 0
		if len(nonOnePositions) > maxNonOne {
			startIdx = nonOnePositions[len(nonOnePositions)-maxNonOne-1] + 1
		}

		// Breakpoints for l: startIdx, and each pos in relevantNonOne
		// Between breakpoints, product is constant.
		// Segments of l:
		// [startIdx, relevantNonOne[0]-1]: no non-one elements if relevantNonOne[0] > startIdx, product = 1
		// Wait, that's not right. If l <= relevantNonOne[0], then relevantNonOne[0] is included.
		// 
		// Actually: for a given l, the product includes all elements in [l, r].
		// As l decreases, we include more elements.
		// As l increases, we exclude elements from the left.
		//
		// Let's think of it differently:
		// Sort candidate l values in decreasing order (from r down to startIdx).
		// The segments are:
		// l in [relevantNonOne[j]+1, relevantNonOne[j+1]] for consecutive j (going left)
		// 
		// Let me define breakpoints more carefully.
		// The "jumps" in product happen when l crosses a position with a[l] > 1.
		// 
		// Specifically:
		// If l > relevantNonOne[last], product = 1 (only 1s in [l,r])
		// Wait no. relevantNonOne contains positions with value > 1 that are in [startIdx, r].
		// 
		// For l in (relevantNonOne[j], relevantNonOne[j+1]] (0-indexed from right):
		// product includes relevantNonOne[j+1..last] elements > 1 from [l,r]
		// 
		// Let me define segments from right to left:
		// Segment 0: l in [relevantNonOne[last]+1, r] if this is nonempty -> but wait we need l <= r
		//   Actually l in [relevantNonOne[len-1]+1, r]: product = 1 (no non-one elements)
		//   Hmm but relevantNonOne[len-1] = r if a[r] > 1.
		//
		// This is getting complicated. Let me just iterate over the at most 61 candidate l values
		// which are: each relevantNonOne position, and the segments between them.
		// For each segment, product is constant, and we check if the required l is in that segment.

		// Build segment boundaries (for l):
		// Segments (from right/large l to left/small l):
		// [relevantNonOne[m-1]+1, r]: if nonempty, product = 1
		// [relevantNonOne[m-2]+1, relevantNonOne[m-1]]: product = a[relevantNonOne[m-1]]
		// ...
		// [startIdx, relevantNonOne[0]]: product = product of all relevantNonOne elements
		//
		// Wait, I need to be careful. For l in a segment, all non-one elements with position >= l and <= r are included.
		
		m := len(relevantNonOne)
		
		// Segments defined by l ranges:
		// seg[i]: l in [leftBound[i], rightBound[i]], product = prod of a[relevantNonOne[i..m-1]]
		// seg[m]: l in [startIdx, relevantNonOne[0]-1] if m > 0, or l in [startIdx, r] if m == 0
		//         but for seg[m], l must be <= relevantNonOne[0]-1, meaning no elements from relevantNonOne are included
		//         Hmm wait.
		
		// Let me re-index. relevantNonOne[0] is the leftmost, relevantNonOne[m-1] is the rightmost (= r if a[r]>1).
		
		// For l in [relevantNonOne[j-1]+1, relevantNonOne[j]] (for j from 0 to m, where relevantNonOne[-1] = startIdx-1 and relevantNonOne[m] = r+1... no this doesn't work cleanly)
		
		// Simplest approach: just compute product for each of the ~60 non-one starting positions
		// and also handle the "only ones" segments.
		
		// Actually, let me just iterate over the at most maxNonOne+1 segments:
		
		// segment j (0-indexed, j from 0 to m):
		// - includes the last (m-j) elements of relevantNonOne (indices j..m-1)
		// - l ranges from (j==0 ? startIdx : relevantNonOne[j-1]+1) to (j==m ? r : relevantNonOne[j]-1)
		// Wait this doesn't make sense dimensionally. Let me think again.
		
		// For j from 0 to m (j = number of non-one elements from relevantNonOne included, from the right):
		// j=0: l in [relevantNonOne[m-1]+1, r], product = 1
		//   (if m==0, then l in [startIdx, r], product = 1)
		// j=1: l in [relevantNonOne[m-2]+1, relevantNonOne[m-1]], product = a[relevantNonOne[m-1]]
		//   (if m==1, then l in [startIdx, relevantNonOne[0]], product = a[relevantNonOne[0]])
		// ...
		// j=m: l in [startIdx, relevantNonOne[0]], product = product of all relevantNonOne
		// Hmm but for j=1, does l in [relevantNonOne[m-2]+1, relevantNonOne[m-1]] correctly include only relevantNonOne[m-1]?
		// Yes! Because l > relevantNonOne[m-2] means relevantNonOne[m-2] is not in [l, r], and l <= relevantNonOne[m-1] means relevantNonOne[m-1] is in [l, r].
		
		// So for j included non-one elements (the rightmost j), l in [lMin_j, lMax_j]:
		// j=0: lMax = r, lMin = (m > 0 ? relevantNonOne[m-1]+1 : startIdx)
		// j=1..m-1: lMax = relevantNonOne[m-j], lMin = relevantNonOne[m-j-1]+1
		// j=m: lMax = relevantNonOne[0], lMin = startIdx
		
		// But wait for j=0 and m==0: lMin = startIdx, lMax = r. OK.
		// For j=0 and m>0: lMin = relevantNonOne[m-1]+1, lMax = r.
		//   If a[r] > 1, then relevantNonOne[m-1] = r, so lMin = r+1 > r = lMax -> empty segment. Correct.
		
		// For j from 1 to m:
		// The j-th non-one element from the right is relevantNonOne[m-j] (0-indexed).
		// Product includes relevantNonOne[m-j], ..., relevantNonOne[m-1].
		// lMax = relevantNonOne[m-j] (l must be <= this position to include it)
		// lMin = (j < m ? relevantNonOne[m-j-1]+1 : startIdx) (l must be > previous non-one pos)
		
		// For each such segment, product P is fixed.
		// We need P / sum([l,r]) = k, i.e., sum = P / k (integer division must be exact).
		// sum([l,r]) = prefix[r+1] - prefix[l]
		// So prefix[l] = prefix[r+1] - P/k
		// This gives a unique l. Check if l is in [lMin, lMax].
		
		// But P can be a big number. Let me use big.Int.
		
		bigProd := big.NewInt(1)
		
		checkSegment := func(lMin, lMax int, prod *big.Int) {
			if lMin > lMax {
				return
			}
			// Need prod / k = sum, and prod % k == 0
			rem := new(big.Int)
			sumNeeded, rem2 := new(big.Int).DivMod(prod, bigK, rem)
			if rem2.Sign() != 0 {
				return
			}
			// sum([l,r]) = sumNeeded => prefix[r+1] - prefix[l] = sumNeeded
			// prefix[l] = prefix[r+1] - sumNeeded
			targetPrefix := new(big.Int).SetInt64(prefix[r+1])
			targetPrefix.Sub(targetPrefix, sumNeeded)
			
			if !targetPrefix.IsInt64() {
				return
			}
			targetPrefixVal := targetPrefix.Int64()
			if targetPrefixVal < 0 {
				return
			}
			
			// Find l such that prefix[l] = targetPrefixVal, l in [lMin, lMax]
			// prefix is non-decreasing (all elements >= 1)
			// Binary search for targetPrefixVal in prefix[lMin..lMax]
			// prefix[l] = targetPrefixVal means prefix[r+1] - prefix[l] = sumNeeded (as int64)
			
			// But sumNeeded might exceed int64. Check.
			// Actually sum of segment <= n * 1e8 = 2e5 * 1e8 = 2e13, which fits in int64.
			if !sumNeeded.IsInt64() {
				return
			}
			sumNeededVal := sumNeeded.Int64()
			if sumNeededVal <= 0 {
				return
			}
			
			// We need prefix[l] = targetPrefixVal in [prefix[lMin], prefix[lMax]]
			if targetPrefixVal < prefix[lMin] || targetPrefixVal > prefix[lMax] {
				return
			}
			
			// Binary search
			lo, hi := lMin, lMax
			for lo < hi {
				mid := (lo + hi) / 2
				if prefix[mid] < targetPrefixVal {
					lo = mid + 1
				} else {
					hi = mid
				}
			}
			if prefix[lo] == targetPrefixVal {
				// Verify sum
				actualSum := sumRange(lo, r)
				_ = actualSum
				count++
			}
		}
		
		// Segment j=0 (0 non-one elements included)
		lMax0 := r
		lMin0 := startIdx
		if m > 0 {
			lMin0 = relevantNonOne[m-1] + 1
		}
		checkSegment(lMin0, lMax0, big.NewInt(1))
		
		// Segments j=1..m
		for j := 1; j <= m; j++ {
			// Include relevantNonOne[m-j..m-1]
			// bigProd *= a[relevantNonOne[m-j]]
			bigProd.Mul(bigProd, big.NewInt(a[relevantNonOne[m-j]]))
			
			lMaxJ := relevantNonOne[m-j]
			lMinJ := startIdx
			if j < m {
				lMinJ = relevantNonOne[m-j-1] + 1
			}
			
			checkSegment(lMinJ, lMaxJ, bigProd)
			
			// Early termination: if product > k * maxPossibleSum, no point continuing
			// maxPossibleSum = n * 1e8 = 2e13
			maxSum := int64(n) * int64(1e8)
			maxProd := new(big.Int).Mul(bigK, big.NewInt(maxSum))
			if bigProd.Cmp(maxProd) > 0 {
				break
			}
		}
	}
	
	return count
}
```