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...
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 (a prime ), then each must have all its set bits among the bits of . In other words, for all , meaning each is a “submask” of .
Reformulation
For each prime :
- Let be the set of primes that are submasks of .
- We need -tuples from whose OR equals exactly .
By inclusion-exclusion on the bits of , the count of -tuples from whose OR is exactly can be computed using Mobius inversion on the subset lattice.
Subset Sum Mobius Inversion
Let number of primes that are submasks of . Then the number of -tuples with OR is . By Mobius inversion:
where the sum is over all submasks of , and denote popcount.
Wait, the Mobius function on the subset lattice is , so:
Then .
Computing
can be computed using the subset sum (zeta) transform over all masks.
For : primes up to , binary length up to 20 bits. The zeta transform runs in which is feasible.
Large Exponent
Since is a prime, and we work modulo , computing is done via modular exponentiation.
Verification
: Primes : . The valid tuples with prime and : , , , , . 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.
Complexity
- Sieve primes: .
- Subset zeta transform: where .
- Mobius inversion per prime : submasks, summed over all primes.
- Total: .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#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;
}
"""
Problem 734: A Bit of Prime
T(n, k) = count of k-tuples of primes <= n whose bitwise OR is also prime <= n.
Uses subset zeta transform and Mobius inversion on the boolean lattice.
"""
MOD = 10**9 + 7
def sieve(n):
"""Sieve of Eratosthenes."""
is_p = [False, False] + [True] * (n - 1)
for i in range(2, int(n**0.5) + 1):
if is_p[i]:
for j in range(i*i, n+1, i):
is_p[j] = False
return is_p
def solve(n, k):
is_p = sieve(n)
primes = [p for p in range(2, n+1) if is_p[p]]
bits = n.bit_length()
size = 1 << bits
# f[m] = number of primes that are submasks of m
f = [0] * size
for p in primes:
if p < size:
f[p] += 1
# Subset zeta transform: f[m] = sum_{s subset m} f_original[s]
for i in range(bits):
for m in range(size):
if m & (1 << i):
f[m] += f[m ^ (1 << i)]
# For each prime q, compute g(q) via Mobius inversion
total = 0
for q in primes:
# Enumerate submasks of q
gq = 0
# Use submask enumeration
s = q
while True:
sign = (-1) ** (bin(q).count('1') - bin(s).count('1'))
fk = pow(f[s], k, MOD)
gq = (gq + sign * fk) % MOD
if s == 0:
break
s = (s - 1) & q
total = (total + gq) % MOD
return total % MOD
# Verify
t5_2 = solve(5, 2)
print(f"T(5, 2) = {t5_2}") # Expected: 5
assert t5_2 == 5
t100_3 = solve(100, 3)
print(f"T(100, 3) = {t100_3}") # Expected: 3355
# T(1000, 10) is feasible
t1000_10 = solve(1000, 10)
print(f"T(1000, 10) mod 10^9+7 = {t1000_10}") # Expected: 2071632
# Full: T(10^6, 999983) - needs optimization for large n
# print(f"T(10^6, 999983) = {solve(10**6, 999983)}")