Block Partitioning for Summing Numbers with Odd Bit Count

Problem Transformation

The core task reduces to computing the sum of all numbers in ([0, N]) whose popcount is odd:

$$\sum_{i=0}^{N} [popcount(i) \bmod 2 = 1]$$

where the Iverson bracket ([p]) equals 1 when (p) is true and 0 otherwise.

Block Partitioning Strategy

When analyzing addition contributions of all numbers in ([0, N]) under binary representation, a common effective approach involves halving the exponent range.

If we have the property (L(a^{x+y}) = L(a^{x}) \cdot L(a^{y})), an (O(a^{x+y})) problem can be reduced to (O(\max(a^{x}, a^{y}))).

Division Decomposition

Consider the divition with remainder: (v = 2^{k} \cdot x + r) where (0 \leq r < 2^{k}) and (2^{k} \leq N). Here (k) is treated as a constant.

Each block contains the full range (0 \sim 2^{k} - 1) for its remainder. The interval ([0, N]) with (N + 1) numbers splits into:

$$\lceil (N + 1) / 2^{k} \rceil = \lfloor N / 2^{k} \rfloor + 1$$

blocks. Number these blocks by (x = 0, 1, 2, \ldots, \lfloor N / 2^{k} \rfloor):

$$\begin{aligned} &[0 \cdot 2^{k} + 0, 0 \cdot 2^{k} + 1, \cdots, 0 \cdot 2^{k} + 2^{k} - 1] \ &[1 \cdot 2^{k} + 0, 1 \cdot 2^{k} + 1, \cdots, 1 \cdot 2^{k} + 2^{k} - 1] \ &[2 \cdot 2^{k} + 0, 2 \cdot 2^{k} + 1, \cdots, 2 \cdot 2^{k} + 2^{k} - 1] \ &\vdots \ &[m \cdot 2^{k} + 0, m \cdot 2^{k} + 1, \cdots, m \cdot 2^{k} + q = N \ (0 \leq q < 2^{k})] \end{aligned}$$

For (x = 0, 1, 2, \ldots, \lfloor N / 2^{k} \rfloor - 1), every block is complete. The block where (x = \lfloor N / 2^{k} \rfloor) may be incomplete, meaning (r) does not span the full range.

Complete Block Analysis

Take a complete block where (0 \leq x < \lfloor N / 2^{k} \rfloor).

Since (r) occupies at most (k) bits, we have:

$$popcount(v = 2^{k} \cdot x + r) = popcount(v = (x \ll k) + r) = popcount(x) + popcount(r)$$

Each block corresponds to a unique (x), so (popcount(x)) is fixed. The block's contribution becomes:

$$\sum_{\substack{r = 0, \ popcount(x) + popcount(r) \equiv 1 \pmod{2}}}^{2^{k} - 1} x \cdot 2^{k} + r$$

Parity Distribution in Complete Range

Consider choosing certain positions to set to 1 (others to 0). The following identities hold:

$$\begin{aligned} \binom{k}{0} + \binom{k}{2} + \binom{k}{4} + \cdots + \binom{k}{2\lfloor k/2\rfloor} + \binom{k}{1} + \binom{k}{3} + \binom{k}{5} + \cdots + \binom{k}{2\lceil k/2\rceil - 1} = 2^{k} \ \binom{k}{0} + \binom{k}{2} + \binom{k}{4} + \cdots + \binom{k}{2\lfloor k/2\rfloor} = \binom{k}{1} + \binom{k}{3} + \binom{k}{5} + \cdots + \binom{k}{2\lceil k/2\rceil - 1} = 2^{k-1} \end{aligned}$$

This requires (0 \sim 2^{k} - 1) to be consecutive with an even count.

An alternative elegant proof leverages the (2^{k}) being a power of 2: for any (x \in [0, 2^{k} - 1]), let (y = x \oplus 1). If (2 | x), then (y) is odd; if (2 \nmid x), then (y) is even. This establishes a bijection between even and odd numbers in the set, each containing exactly (2^{k-1}) elements.

Thus the block contribution simplifies to:

$$\begin{aligned} &x \cdot 2^{k} \cdot 2^{k-1} + \sum_{\substack{r = 0, \ popcount(x) + popcount(r) \equiv 1 \pmod{2}}}^{2^{k}-1} r \ &= x \cdot 2^{k} \cdot 2^{k-1} + \begin{cases} \sum_{\substack{r = 0, \ popcount(r) \equiv 0 \pmod{2}}}^{2^{k}-1} r, & popcount(x) \equiv 1 \pmod{2}; \ \sum_{\substack{r = 0, \ popcount(r) \equiv 1 \pmod{2}}}^{2^{k}-1} r, & popcount(x) \equiv 0 \pmod{2}. \end{cases}\end{aligned}$$

Precompute these two sums in (O(2^{k})):

$$\begin{aligned} S_{even} &= \sum_{\substack{r = 0, \ popcount(r) \equiv 0 \pmod{2}}}^{2^{k} - 1} r \ S_{odd} &= \sum_{\substack{r = 0, \ popcount(r) \equiv 1 \pmod{2}}}^{2^{k} - 1} r \end{aligned}$$

The complete blocks require (O(1)) computation per block, totaling (\lfloor N / 2^{k} \rfloor) iterations.

Incomplete Block Handling

For the final block where (x = \lfloor N / 2^{k} \rfloor), iterate through (r \in [x \cdot 2^{k}, N]). If (popcount(x)) and (popcount(r)) have different parity, add (x \cdot 2^{k} + r) to the result.

Complexity Analysis

Time complexity: (O(\max(N / 2^{k}, 2^{k}))). Choosing (k) as roughly half the binary length of (N) yields (O(\sqrt{N})) by the property (2^{a} \cdot 2^{b} = 2^{a+b}).

Closed-Form Optimization

For (k \geq 2), a useful identity emerges:

$$\sum_{\substack{i = 0, \ popcount(i) \equiv 0 \pmod{2}}}^{2^{k} - 1} i = \sum_{\substack{i = 0, \ popcount(i) \equiv 1 \pmod{2}}}^{2^{k} - 1} i = \frac{\binom{2^{k}}{2}}{2} = 2^{k-2} \cdot (2^{k} - 1)$$

Inductive proof: For (k \geq 2), the four numbers (00, 01, 10, 11) satisfy (S_{even} = S_{odd} = \sum_{i=0}^{2^{k}-1} i). When extending to (k+1) bits by adding a high bit, each number receives an additional (2^{k}) contribution while preserving the equality of counts and sums.

This leads to a simplified block contribution formula:

$$\begin{aligned} &x \cdot 2^{k} \cdot 2^{k-1} + 2^{k-2} \cdot (2^{k} - 1) \ &= 2^{2k-1} \cdot x + 2^{2k-2} - 2^{k-2} \end{aligned}$$

For the first term, let (M = \lfloor N / 2^{k} \rfloor). The contribution becomes:

$$2^{2k-1} \cdot \sum_{x=0}^{M-1} \binom{x}{1} = 2^{2k-1} \cdot \binom{M}{2} = 2^{2k-2} \cdot M \cdot (M-1)$$

For the constant term (2^{2k-2} - 2^{k-2}):

$$\sum_{x=0}^{M-1} (2^{2k-2} - 2^{k-2}) = (2^{2k-2} - 2^{k-2}) \cdot M$$

Both components reduce to (O(1)) computation, making the overall complexity (O(2^{k})).

Since the formula requires (k \geq 2), setting (k = 2) yields optimal (O(1)) time complexity.

Implementation

#include <iostream>

constexpr int K = 2;
constexpr int64_t BLOCK_SIZE = int64_t(1) << K;

int64_t prefix_sum(int64_t N) {
    if (N <= 0) return 0;
    
    int64_t block_count = N / BLOCK_SIZE;
    int64_t remainder = N % BLOCK_SIZE;
    
    int64_t result = 0;
    
    // Process all complete blocks using closed-form formula
    result += int64_t(1) << (2 * K - 2) * block_count * (block_count - 1);
    result += ((1 << (2 * K - 2)) - (1 << (K - 2))) * block_count;
    
    // Handle the incomplete final block by brute force
    int x = static_cast<int>(block_count);
    for (int r = 0; r <= remainder; ++r) {
        if ((__builtin_popcount(r) + __builtin_popcount(x)) & 1) {
            result += x * BLOCK_SIZE + r;
        }
    }
    
    return result;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int64_t lower, upper;
    std::cin >> lower >> upper;
    
    std::cout << prefix_sum(upper) - prefix_sum(lower - 1) << '\n';
    
    return 0;
}

Edge Case Considerations

When the lower bound equals 1, the open interval becomes 0. Single-element cases like (N = 0) require special handling depending on specific problem requirements.

Tags: Competitive Programming Bit Manipulation block partitioning population count mathematical optimization

Posted on Sun, 11 Oct 2026 16:57:57 +0000 by Pig