Skip to main content

Bitwise Sieve w/ code sample

Sieve of Eratosthenes is explained HERE
Bitwise sieve is an optimized implementation of  Sieve of Eratosthenes. It does the same thing but more memory efficient because it uses logic operations( &,|,>>,<< ) on binary numbers.

In normal implementation, we use an array as flag to check if a number is prime or not.we know index of an array ( i.e  myarray[n]  ) is 32 bit long. If an array is 10 index long, that it has 32x10(=320) bits.  We use bits of that array as flag. that way we can flag numbers upto 320 as prime or not prime. i.e, how to check the flag status of 51 in myarray[ n ] ? We'll divide 5 by 32, that will give us the index number of the certain bit, then we'll mod 5 by 32, that will give us the certain bit position to check for 0 or 1. Remember bit positions are defined from right to left, starting from 0. Meaning LST = 0 and MST = 31.
So we need to define two functions, one to set that certain bit as 0 or 1, another to check if  bit is 0 or 1.

#define check(arr,n) ( (arr[n/32]>>(n%32))&1 )
#define sett(arr,n) ( arr[n/32] = arr[n>>5] | (1<<(n%32) ))
* I've used macros, but you can write the same code in functions if you want.

CHECK: now in case of 51, (51/32)= 1, so the the bit flag is index 1. the bit position is (51%32)=19.
this means we'll have to check 19th bit of myarray[1] . To understand the next part, you need to know bit operation and bit masking.

BITWISE OPS | BITMASKING

assuming you know bitwise operations, we right shifted myarray[1] 19 times ( myarray[1] >>19 ) and then performed AND operation to see if the bit is 0 or 1. The latter is a bitmask.

SETT: we use same procedure to find the index number and bit position. Then set that bit as we want by another bitmask.

sample:


#include<bits/stdc++.h> using namespace std; #define MAX 46340                        // to find primes from 2 to 46340 #define MAXh 216                          // sqrt of 46340 #define check(arr,n) ( (arr[n/32]>>(n%32))&1 ) #define sett(arr,n) ( arr[n/32] = arr[n>>5] | (1<<(n%32) )) unsigned int prime[100000], flag[MAX/32]; void sieve() {     unsigned int i,j,k,id=0;     for(i=3;i<=MAXh;i+=2)     {         if(!check(flag,i))         {             for(j=i*i;j<=MAX;j+=i)             {                 sett(flag,j);             }         }     }
    prime[id++]=2;     for(i=3;i<=MAX;i+=2)     {         if(!check(flag,i))  prime[id++]=i;     } }
If there's any wrong information or explanation, please let me know.

Comments

Popular posts from this blog

SPOJ - GSS1

Considering input series: { 4 , -10 , 3 , 100 , -20 , 1 } Query(x,y) = Max { a[i]+a[i+1]+...+a[j] ; x ≤ i ≤ j ≤ y } A node contains-  [ START & END is a node's segment limit ] Prefix is the maximum sum starting at START, end can be anywhere. There are two possibilities of the maximum. One, node's leftChild's prefix or two, adding leftChild's sum + rightChild's prefix. (which will make the prefix contiguous) Suffix is the maximum sum ending at END, start can be anywhere. There's two possibility of the maximum. One, node's rightChild's already calculated suffix or two, add rightChild's sum + leftChild's suffix   (which will make the suffix contiguous). Sum : leftChild's sum + rightChild's sum. MAX Maximum of  -  prefix (result is in the node, starts from START but doesn't end in END ) suffix  (result is in the node, doesn't start from START but surely ends in END ) leftChild's max ( result is in left ...

SPOJ 95 - STPAR - Street Parade

Problem Statement Heuristics:   Let, N be the number which is next in fixed order. Take an input X , if it is equal to N then next number will be n++. If not, then search for N in the side lane and after finishing the search, put X in the side lane. After all X is processed but N is not found in either X or side lane, then the order is not possible. Solution:

SPOJ 394- ACODE

Problem Statement As from the problem-tag, you can see this is a DP( Dynamic Programming ) problem. Don't know Dynamic Programming? Here are some articles: Codechef , TopCoder . Try to solve a sample problem, for example, Fibonacci Numbers. Let's start cracking the problem. To solve a DP problem, the hardest and important part is to find the relation between previous or next steps and current step . We need to find out how the solution of the current step depends on its previous steps or next steps. Looking at:      2 5 1 1 4        from left to right Step 1: You can only interpret this as 2(B). Decoding- B EAAD  So, DP[1] = 1 Step 2: This can be 5(E) or collaborating with 2, it can be 25(Y). Result is BE AAD + Y AAD . So, DP[2] = 2 Step 3: Can only be interpreted as 1(A). 51 is not valid, as stated in problem. BEA AD + YA AD . DP[3] = 2.  Step 4: Will be interpreted as 1(A). BEAA D + YAA D+... ...