All Euler problems
Project Euler

A Bit of Prime

The bitwise-OR of integers performs logical OR on each pair of binary digits. Define T(n, k) as the number of k -tuples (x_1, x_2,..., x_k) where: Each x_i is prime and <= n x_1 mathbin| x_2 mathbi...

Source sync Apr 19, 2026
Problem #0734
Level Level 25
Solved By 403
Languages C++, Python
Answer 557988060
Length 303 words
modular_arithmeticnumber_theorylinear_algebra

Problem Statement

This archive keeps the full statement, math, and original media on the page.

The logical-OR of two bits is $0$ if both bits are $0$, otherwise it is $1$.

The bitwise-OR of two positive integers performs a logical-OR operation on each pair of corresponding bits in the binary expansion of its inputs.

For example, the bitwise-OR of $10$ and $6$ is $14$ because $10 = 1010_2$, $6 = 0110_2$ and $14 = 1110_2$.

Let $T(n, k)$ be the number of $k$-tuples $(x_1, x_2,\cdots,x_k)$ such that:

  • every $x_i$ is a prime $\leq n$

  • the bitwise-OR of the tuple is a prime $\leq n$

For example, $T(5, 2)=5$. The five $2$-tuples are $(2, 2)$, $(2, 3)$, $(3, 2)$, $(3, 3)$ and $(5, 5)$.

You are given $T(100, 3) = 3355$ and $T(1000, 10) \equiv 2071632 \pmod{1\,000\,000\,007}$.

Find $T(10^6,999983)$. Give your answer modulo $1\,000\,000\,007$.

Problem 734: A Bit of Prime

Mathematical Analysis

Structure of OR-Closed Prime Sets

If p1p2pk=qp_1 \mathbin{|} p_2 \mathbin{|} \cdots \mathbin{|} p_k = q (a prime n\le n), then each pip_i must have all its set bits among the bits of qq. In other words, pi&q=pip_i \mathbin{\&} q = p_i for all ii, meaning each pip_i is a “submask” of qq.

Reformulation

For each prime qnq \le n:

  • Let B(q)={p prime:pn,p&q=p}B(q) = \{p \text{ prime} : p \le n, p \mathbin{\&} q = p\} be the set of primes that are submasks of qq.
  • We need kk-tuples from B(q)B(q) whose OR equals exactly qq.

By inclusion-exclusion on the bits of qq, the count of kk-tuples from B(q)B(q) whose OR is exactly qq can be computed using Mobius inversion on the subset lattice.

Subset Sum Mobius Inversion

Let f(m)=B(m)=f(m) = |B(m)| = number of primes that are submasks of mm. Then the number of kk-tuples with OR m\subseteq m is f(m)kf(m)^k. By Mobius inversion:

g(q)=mq(1)qmf(m)kg(q) = \sum_{m \subseteq q} (-1)^{|q|-|m|} f(m)^k

where the sum is over all submasks mm of qq, and q,m|q|, |m| denote popcount.

Wait, the Mobius function on the subset lattice is μ(m,q)=(1)qm\mu(m, q) = (-1)^{|q \setminus m|}, so:

g(q)=mq(1)popcount(q)popcount(m)f(m)kg(q) = \sum_{m \subseteq q} (-1)^{\text{popcount}(q) - \text{popcount}(m)} f(m)^k

Then T(n,k)=q prime,qng(q)T(n, k) = \sum_{q \text{ prime}, q \le n} g(q).

Computing f(m)f(m)

f(m)=p prime,pn,pm1f(m) = \sum_{p \text{ prime}, p \le n, p \subseteq m} 1 can be computed using the subset sum (zeta) transform over all masks.

For n=106n = 10^6: primes up to 10610^6, binary length up to 20 bits. The zeta transform runs in O(22020)O(2^{20} \cdot 20) which is feasible.

Large Exponent k=999983k = 999983

Since k=999983k = 999983 is a prime, and we work modulo 109+710^9+7, computing f(m)kmodpf(m)^k \bmod p is done via modular exponentiation.

Verification

T(5,2)=5T(5, 2) = 5: Primes 5\le 5: {2,3,5}\{2, 3, 5\}. The valid tuples (x1,x2)(x_1, x_2) with x1x2x_1|x_2 prime and 5\le 5: (2,2)2(2,2)\to 2, (2,3)3(2,3)\to 3, (3,2)3(3,2)\to 3, (3,3)3(3,3)\to 3, (5,5)5(5,5)\to 5. Count = 5. Confirmed.

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity

  • Sieve primes: O(n)O(n).
  • Subset zeta transform: O(2bb)O(2^b \cdot b) where b=log2n20b = \lceil\log_2 n\rceil \approx 20.
  • Mobius inversion per prime qq: O(2popcount(q))O(2^{\text{popcount}(q)}) submasks, summed over all primes.
  • Total: O(n/lnn2bmax+2bb)O(n/\ln n \cdot 2^{b_{\max}} + 2^b \cdot b).

Answer

557988060\boxed{557988060}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_734/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 734: A Bit of Prime
 *
 * T(n, k) = number of k-tuples of primes with OR also prime.
 * Subset zeta transform + Mobius inversion on boolean lattice.
 */

const int MOD = 1e9 + 7;

long long power(long long base, long long exp, long long mod) {
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

int main() {
    int n = 1000000;
    long long k = 999983;

    // Sieve
    vector<bool> is_p(n + 1, true);
    is_p[0] = is_p[1] = false;
    for (int i = 2; (long long)i*i <= n; i++)
        if (is_p[i]) for (int j = i*i; j <= n; j += i) is_p[j] = false;

    int bits = 0;
    while ((1 << bits) <= n) bits++;
    int sz = 1 << bits;

    // f[m] = count of primes that are submasks of m
    vector<int> f(sz, 0);
    for (int p = 2; p <= n; p++)
        if (is_p[p]) f[p]++;

    // Zeta transform
    for (int i = 0; i < bits; i++)
        for (int m = 0; m < sz; m++)
            if (m & (1 << i)) f[m] += f[m ^ (1 << i)];

    // For each prime q, Mobius inversion
    long long total = 0;
    for (int q = 2; q <= n; q++) {
        if (!is_p[q]) continue;
        int qbits = __builtin_popcount(q);
        long long gq = 0;
        // Enumerate submasks
        for (int s = q; ; s = (s - 1) & q) {
            int sbits = __builtin_popcount(s);
            long long sign = ((qbits - sbits) & 1) ? MOD - 1 : 1;
            gq = (gq + sign % MOD * power(f[s], k, MOD)) % MOD;
            if (s == 0) break;
        }
        total = (total + gq) % MOD;
    }

    printf("%lld\n", total);
    return 0;
}