cppAcademy
FROM LEARNING TO COMPETING

Expert.
Put your skills to the test.

Bulgarian Informatics Group A · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group A also includes challenging national-level problems. The 109 National-round tasks shared by Groups A and B retain their existing permanent URLs and explanations. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP A2010 · MediumPrime sieve

Doubly Prime Numbers

National Olympiad — Regional round (2010 season)

Submission name: dprime.cpp

Problem summary

Count primes in [a,b] whose binary representation can be split into two prime numbers without leading zeros and with bit lengths differing by at most one.

Input

Integers a and b.

Output

The number of qualifying primes.

Constraints

1 ≤ a ≤ b ≤ 50000000.

Worked example

Official statement example.

Input

8 109

Output

7

Solution analysis

  1. Build a sieve of primes through b using packed bits. Only prime candidates need a split test. A split with right-hand length r extracts left=p>>r and right=p modulo 2^r.
  2. If the total bit length is L, balanced pieces require r=L/2 for even L, or r=floor(L/2) and ceil(L/2) for odd L. Require right≥2^(r−1) to exclude leading zeros, then test both pieces in the sieve.
  3. For 29=11101₂, the split 11|101 gives primes 3 and 5 with lengths 2 and 3. For 43=101011₂, the equal split 101|011 fails because the right piece has a leading zero. Count each whole prime at most once.

Why it works

Every allowed decomposition has one of the tested right-piece lengths. Bit extraction produces exactly its two pieces and the leading-bit check enforces the representation rule. The sieve identifies primality exactly, so a whole number is counted precisely when at least one legal split exists.

Complexity: O(b log log b) time for the sieve plus O(b) scanning; O(b) bits of sieve storage.

Watch out. A numeric suffix can be prime despite having a forbidden leading zero in the split.,Do not double-count primes with two valid splits.

Commented C++17 solution

An independently written complete program with standard headers.

// Key idea: Every allowed decomposition has one of the tested right-piece lengths. Bit extraction
// produces exactly its two pieces and the leading-bit check enforces the representation rule.
#include<iostream>
#include<vector>
using namespace std;
int main(){
    int a,b;
    cin>>a>>b;
    vector<bool>prime(b+1,true);
    prime[0]=false;
    if(b>=1){
        prime[1]=false;
    }
    for(int p=2;p<=b/p;++p){
        if(prime[p]){
            for(int v=p*p;v<=b;v+=p){
                prime[v]=false;
            }
        }
    }
    int answer=0,length=1,nextPower=2;
    for(int p=1;p<=b;++p){
        if(p==nextPower){
            ++length;
            nextPower*=2;
        }
        if(p<a||!prime[p]){
            continue;
        }
        bool good=false;
        for(int r=length/2;r<=(length+1)/2;++r){
            if(r==0){
                continue;
            }
            int left=p>>r;
            int right=p&((1<<r)-1);
            if(right>=(1<<(r-1))&&prime[left]&&prime[right]){
                good=true;
            }
        }
        if(good){
            ++answer;
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗