Bitwise Operations was one of the most confusing topics for me at first. But once I started understanding how bits actually work, many CP problems suddenly became much easier to think about and optimize.
This blog is the result of a full day of grinding, where I tried to organize everything I know about bitwise tricks into a clear and structured form — from the basics to useful CP patterns. I tried to keep everything as simple and beginner-friendly as possible so that anyone can understand the core idea behind each trick instead of memorizing formulas. If even one trick from this blog helps someone solve a problem faster or understand bits more clearly, then this effort feels truly meaningful for me.
And finally, I want to express my deepest gratitude to Raha Ahmed for being The Strongest supports in my CP journey. Her constant encouragement, belief and presence have played a huge role in shaping my progress and I’m truly grateful for everything she has done.
The Basics for Beginners :
Basics All - (click here)
Know The Bit
Binary is a number system that uses only two digits: 0 and 1. Each digit is called a bit. A binary number is just a way to represent a decimal number using powers of 2.
Binary : 1 0 1 0
Value : 8 4 2 1
Each position means a power of 2. If the bit is 1, we take that value. If the bit is 0, we ignore it.
So: 1010 = 8 + 2 = 10
and 1101 = 8 + 4 + 1 = 13
We usually read binary from right to left, starting from the 0th bit.
This is important because bitwise operations (AND, OR, XOR, NOT and Shifts) work directly on these bits instead of the decimal value. So if you understand binary properly, all bitwise tricks in CP become much easier to understand.
Watch for Better Idea :-
Bitwise AND (&)
Bitwise AND checks two bits one by one. The result becomes 1 only when both bits are 1. If any one of the bits is 0, the result becomes 0. You can simply think: both need to be 1.
Example :
1010
& 1001
------
1000
10 & 9 = 8
Bitwise OR (|)
Bitwise OR compares two bits one by one. If at least one bit is 1, the result becomes 1. Only 0 | 0 gives 0. You can simply think: one 1 is enough.
Example :
1010
| 1001
------
1011
10 | 9 = 11
Bitwise XOR (^)
Bitwise XOR checks whether two bits are different or not. If the bits are different, the result becomes 1. If both bits are same, the result becomes 0. You can simply think: different means 1.
Example :
1010
^ 1001
------
0011
10 ^ 9 = 3
Bitwise NOT (~)
Bitwise NOT flips every bit of a number. All 1 become 0 and all 0 become 1. It just changes every bit to its opposite value. This operation works on every bit individually.
Example :
~1010 = 0101
~10 = -11
Think => Why does this become negative ? info => ~n = -(n+1) but think How and Why ?
Left Shift (<<)
Left Shift moves all bits to the left by n positions. Every left shift usually multiplies the number by 2. More shifts mean a bigger value. New empty places on the right become 0.
Example 1 :
1010 << 1 = 10100
10 << 1 = 20
Example 2 :
0011 << 2 = 1100
3 << 2 = 12
Right Shift (>>)
Right Shift moves all bits to the right side one by one n times. Every right shift usually divides the number by 2 (integer / floor division). Bits on the right side are removed.
Example 1 :
1010 >> 1 = 0101
10 >> 1 = 5
Example 2 :
10100 >> 2 = 00101
20 >> 2 = 5
1 << x vs 1LL << x
When we write: 1 << x the value 1 is treated as an int. int usually stores up to 32 bits. So for very large shifts, the value can overflow and give wrong results.
But when we write: 1LL << x the 1LL becomes a long long. A long long can store up to 64 bits, so it is much safer for large shifts.
I directly use: 1LL << x to stay safe for large values.