0% found this document useful (0 votes)
6 views

Bitwise Operators_

Uploaded by

chayon das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Bitwise Operators_

Uploaded by

chayon das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

n &= (n - 1);

// Remove the rightmost set bit


Bitwise Operators:
count++;
// AND - returns 1 if both bits are 1, else 0
}
int and_op = a & b;
return count;
// OR - returns 1 if at least one bit is 1
}
int or_op = a | b;
Find the Rightmost Set Bit:
// XOR - returns 1 if bits are different
int rightmostSetBit(int n) {
int xor_op = a ^ b;
return n & (-n);
// NOT - inverts all bits (1 to 0 and vice
// Equivalent to n & (n ^ (n - 1))
versa)
}
int not_op = ~a;
Check if a Number is a Power of 2:
// Left Shift - multiplies by 2^n
bool isPowerOf2(int n) {
int left_shift = a << n;
return (n && (n & (n - 1)) == 0);
// Right Shift - divides by 2^n
// n is a power of 2 if n & (n-1) == 0
int right_shift = a >> n;
}
Converting to Binary Representation:
Fast Operations (Shift Operations for Optimization):
// Convert integer to 32-bit binary
int div2 = n >> 1; // Equivalent to n / 2
representation using bitset
int mul2 = n << 1; // Equivalent to n * 2
bitset<32> binary(n);
STL Functions for Bit Manipulation:
cout << binary; // Print binary
int setBits = __builtin_popcount(n);
// Function to print binary representation
// Counts number of 1's in n
void printBinary(int number, int length) {
int leadingZeros = __builtin_clz(n);
string binary = "";
// Number of leading zeros in n
for (int i = length - 1; i >= 0; i--) {
int trailingZeros = __builtin_ctz(n);
binary += ((number >> i) & 1) ? '1' :
'0'; // Number of trailing zeros in n
} Subset Generation:
cout << binary << endl; // Generate all subsets using bitmasks
} for (int mask = 0; mask < (1 << n); mask++) {
// 2^n (2 power n) for (int i = 0; i < n; i++) {
1 << n if (mask & (1 << i)) {
MSB (Most Significant Bit) and LSB (Least Significant // i-th element is in the subset
Bit): }
// MSB 100111010101, LSB 1010100101 }
Basic Bit Manipulation Tricks: }
bool isOdd = (n & 1); // 1 if odd Subset Sum Problem (Dynamic Programming
bool isEven = !(n & 1); // 1 if even Approach):
// Set the k-th bit bool subsetSum(int arr[], int n, int target)
a |= (1 << k); {
// Clear the k-th bit bool dp[target + 1] = { false };
a &= ~(1 << k); dp[0] = true;
// Toggle the k-th bit for (int i = 0; i < n; i++) {
a ^= (1 << k); for (int j = target; j >= arr[i];
j--) {
// True if k-th bit is 1
dp[j] |= dp[j - arr[i]];
bool isSet = (a & (1 << k)) != 0;
}
Count Set Bits (1’s):
}
int countSetBits(int n) {
return dp[target];
int count = 0;
}
while (n) {
Common Bit Manipulation Problems: if (arr[i] & rightmost_set_bit) {
Find Missing Number in Array: x ^= arr[i]; // First unique
element
int findMissing(int arr[], int n) {
} else {
int xor_all = 0;
y ^= arr[i]; // Second unique
for (int i = 1; i <= n; i++) { element

xor_all ^= i; }

// XOR all numbers from 1 to n }

} }

for (int i = 0; i < n - 1; i++) { XOR from 1 to N:

xor_all ^= arr[i]; int xorUptoN(int n) {

// XOR all elements in the array if (n % 4 == 0) return n;

} if (n % 4 == 1) return 1;

return xor_all; // Missing number if (n % 4 == 2) return n + 1;

} return 0;

Find Maximum of Two Numbers Using XOR: }

int max = a ^ ((a ^ b) & -(a < b)); Maximum XOR Subarray:

// Maximum of a and b int maxXorSubarray(int arr[], int n) {

int min = b ^ ((a ^ b) & -(a < b)); int prefix_xor = 0, max_xor = 0;

// Minimum of a and b set<int> prefix_xors;

Reverse Bits of a Number: prefix_xors.insert(0);

int reverseBits(int n) { // Initialize with 0

int result = 0; for (int i = 0; i < n; i++) {

while (n) { prefix_xor ^= arr[i];

result = (result << 1) | (n & 1); for (auto it : prefix_xors) {

// Shift and add the last bit max_xor = max(max_xor, prefix_xor


^ it);
n >>= 1; }
} prefix_xors.insert(prefix_xor);
return result; }
} return max_xor;
XOR Trick Full Notes for Competitive Programming: }
// 1. Basic XOR Properties Subset XOR:
// - Identity: a ^ a = 0 int subsetXor(int arr[], int n) {
// - Zero: a ^ 0 = a int xor_sum = 0;
// - Commutative: a ^ b = b ^ a for (int mask = 0; mask < (1 << n);
// - Associative: (a ^ b) ^ c = a ^ (b ^ c) mask++)
// - XOR of a number with all set bits: a ^ {
(1 << n) - 1 flips all bits of a up to n bits int subset_xor = 0;
Find Two Non-Repeating Elements in an Array: for (int i = 0; i < n; i++) {
void findTwoUniqueElements(int arr[], int n) if (mask & (1 << i)) {
{ subset_xor ^= arr[i];
int xor_all = 0; }
for (int i = 0; i < n; i++) { }
xor_all ^= arr[i]; xor_sum ^= subset_xor;
} // XOR of all subset XORs
int rightmost_set_bit = xor_all & }
(-xor_all); return xor_sum;
}
int x = 0, y = 0; // Two unique elements
for (int i = 0; i < n; i++) { Find the Majority Element Using XOR:
int majorityElement(int arr[], int n) { vector<int> diff(n + 1, 0); // Extra space to handle R+1
int majority = 0; index
for (int i = 0; i < n; i++) { diff[0] = arr[0];
majority ^= arr[i];
} for (int i = 1; i < n; ++i) {

return majority; diff[i] = arr[i] - arr[i - 1];


}
}
XOR for Range Queries:
return diff;
}
int xorInRange(int prefixXor[], int i, int j)
{
// Function to apply a range update to the difference array
if (i == 0) return prefixXor[j];
void applyRangeUpdate(vector<int>& diff, int L, int R, int val)
return prefixXor[j] ^ prefixXor[i - 1]; {

} diff[L] += val;

// Function to compute the 2D prefix sum if (R + 1 < diff.size()) {

vector<vector<int>> compute2DPrefixSum(const diff[R + 1] -= val;

vector<vector<int>>& matrix) { }

int rows = matrix.size(); }

int cols = matrix[0].size();


// Function to reconstruct the original array after updates

// Create a prefix sum matrix with the same dimensions vector<int> getUpdatedArray(const vector<int>& diff) {

vector<vector<int>> prefix(rows, vector<int>(cols, 0)); int n = diff.size();


vector<int> arr(n - 1, 0); // Resulting array

// Compute the prefix sums


for (int i = 0; i < rows; ++i) { arr[0] = diff[0];

for (int j = 0; j < cols; ++j) { for (int i = 1; i < n - 1; ++i) {

prefix[i][j] = matrix[i][j] arr[i] = arr[i - 1] + diff[i];

+ (i > 0 ? prefix[i - 1][j] : 0) // Add value }


from the top cell
+ (j > 0 ? prefix[i][j - 1] : 0) // Add value
from the left cell return arr;
- (i > 0 && j > 0 ? prefix[i - 1][j - 1] : 0); // }
Subtract overlap
} //Binary Exponentiation

} long long binExpo(long long a, long long b, long long m) {

return prefix; long long result = 1;

} a = a % m;
while (b > 0) {

// Function to query the sum of a submatrix using the prefix if (b % 2 == 1)

sum result = (result * a) % m;

int query2DPrefixSum(const vector<vector<int>>& prefix, int a = (a * a) % m;

x1, int y1, int x2, int y2) { b /= 2;

int total = prefix[x2][y2]; }

if (x1 > 0) total -= prefix[x1 - 1][y2]; return result;

if (y1 > 0) total -= prefix[x2][y1 - 1]; }

if (x1 > 0 && y1 > 0) total += prefix[x1 - 1][y1 - 1]; //Fermat's Little Theorem and Modular Inverse

return total; long long modInverse(long long a, long long p) {

} return binExpo(a, p - 2, p);


}

// Function to initialize the difference array //nCr and nPr

vector<int> initializeDifferenceArray(const vector<int>& arr) { vector<long long> fact(MAX_A + 1), inv(MAX_A + 1);

int n = arr.size();
// Function to compute modular exponentiation
long long mod_exp(long long base, long long exp, int mod) { vector<int> primes;
long long result = 1; void sieve(int n = MAXN) {
while (exp > 0) { is_prime[0] = is_prime[1] = false;
if (exp % 2 == 1) result = (result * base) % mod; for (int i = 2; i <= n; i++) {
base = (base * base) % mod; if (is_prime[i]) {
exp /= 2; primes.pb(i);
} for (int j = 2 * i; j <= n; j += i) {
return result; is_prime[j] = false;
} }
// Precompute factorials and modular inverses }
void precompute() { }
fact[0] = 1; }
for (int i = 1; i <= MAX_A; i++) { //segmentedSieve
fact[i] = (fact[i - 1] * i) % MOD; vector<long long> Sieve(long long limit) {
} vector<bool> isPrime(limit + 1, true);
inv[MAX_A] = mod_exp(fact[MAX_A], MOD - 2, MOD); isPrime[0] = isPrime[1] = false;
for (int i = MAX_A - 1; i >= 0; i--) {
inv[i] = (inv[i + 1] * (i + 1)) % MOD;
} for (long long i = 2; i * i <= limit; ++i) {
} if (isPrime[i]) {
// Function to calculate binomial coefficient for (long long j = i * i; j <= limit; j += i) {
(nCr)=n!/(r!*(n-r)!) isPrime[j] = false;
modulo MOD }
long long binomial_coefficient(int n, int r) { }
if (r > n) return 0; }
return fact[n] * inv[r] % MOD * inv[n - r] % MOD; vector<long long> primes;
} for (long long i = 2; i <= limit; ++i) {
if (isPrime[i]) {
// Function to calculate permutation (nPr)=n!/(n-r)! primes.push_back(i);
modulo }
MOD }
long long permutation(int n, int r) { return primes;
if (r > n) return 0; }
return fact[n] * inv[n - r] % MOD; vector<long long> segmentedSieve(long long L, long long U)
} {
long long limit = floor(sqrt(U)) + 1;
//Stars and Bars C(n+k−1,k−1) vector<long long> primes = Sieve(limit);
vector<bool> isPrime(U - L + 1, true);
//Pigeonhole Principle for (long long p : primes)
bool pigeonholeExample(const vector<int>& arr, int m) { {
unordered_map<int, int> freq; long long start = max(p * p, (L + p - 1) / p * p);
for (int x : arr) { for (long long j = start; j <= U; j += p) {
if (++freq[x] > m) { isPrime[j - L] = false;
return true; }
} }
} vector<long long> primeNumbers;
return false; for (long long i = max(L, 2LL); i <= U; ++i)
} {
if (isPrime[i - L]) {
// Sieve of Eratosthenes to find primes up to n primeNumbers.push_back(i);
vector<bool> is_prime(MAXN, true); }
} }
return primeNumbers; }
} return spf;
// Prime Factorization of a number }
vector<int> prime_factors(int n) {
vector<int> factors; vector<int> prime_factorization(int n, const vector<int>& spf)
{
for (int i = 2; i * i <= n; i++) {
vector<int> factors;
while (n % i == 0) {
while (n != 1) {
factors.push_back(i);
factors.push_back(spf[n]);
n /= i;
n /= spf[n];
}
}
}
return factors;
if (n > 1) factors.push_back(n);
}
return factors;
// Divisors of a number
}
vector<int> divisors(int n) {
//The least prime factor (LPF) of a number n is the
vector<int> divs;
smallest
for (int i = 1; i * i <= n; i++) {
prime number that divides n without a remainder
if (n % i == 0) {
vector<int> leastPrimeFactor(int n) {
divs.push_back(i);
vector<int> lpf(n + 1, 0);
if (i != n / i) divs.push_back(n / i);
lpf[1] = 1;
}
}
for (int i = 2; i <= n; i++) {
return divs;
if (lpf[i] == 0) {
}
lpf[i] = i;
// Euler's Totient Function (Phi function)
for (int j = i * 2; j <= n; j += i) {
int euler_totient(int n) {
if (lpf[j] == 0) {
int result = n;
lpf[j] = i;
for (int i = 2; i * i <= n; i++) {
}
if (n % i == 0) {
}
while (n % i == 0) n /= i;
}
result -= result / i;
}
}
}
return lpf;
if (n > 1) result -= result / n;
}
return result;
//Prime Factorization using Sieve O(log n) for multiple
}
queries
//GCD
vector<int> sieve_and_spf(int limit) {
int gcd(int a, int b) {
vector<int> spf(limit + 1);
while (b != 0) {
for (int i = 0; i <= limit; i++) {
int temp = b;
spf[i] = i;
b = a % b;
}
a = temp;
}
return a;
for (int i = 2; i * i <= limit; i++) {
}
if (spf[i] == i) {
//STL gcd
for (int j = i * i; j <= limit; j += i) {
__gcd(a,b)
if (spf[j] == j) {
//LCM
spf[j] = i;
int lcm(int a, int b) {
}
return (a * b) / gcd(a, b);
}
}
// Extended Euclidean Algorithm to find gcd and vector<vector<int>> result = {{1, 0}, {0, 1}};
coefficients while (n) {
int extended_gcd(int a, int b, int &x, int &y) { if (n % 2) result = matrix_mult(result, A);
if (b == 0) { A = matrix_mult(A, A);
x = 1; n /= 2;
y = 0; }
return a; return result;
} }
int gcd = extended_gcd(b, a % b, x, y);
int temp = x; int fib(int n) {
x = y; if (n == 0) return 0;
y = temp - (a / b) * y; vector<vector<int>> F = {{1, 1}, {1, 0}};
return gcd; F = matrix_pow(F, n - 1);
} return F[0][0];
// Chinese Remainder Theorem (CRT) }
int mod_inverse(int a, int m) { //math
int x, y; //Matrix Exponentiation
int g = extended_gcd(a, m, x, y); vector<vector<long long>> mat_mult(vector<vector<long
if (g != 1) return -1; // No solution long>>& A, vector<vector<long long>>& B, int mod) {
return (x % m + m) % m; int n = A.size();
} vector<vector<long long>> result(n, vector<long long>(n,
0));
int chinese_remainder_theorem(vector<int> &a, vector<int>
for (int i = 0; i < n; i++) {
&m) {
for (int j = 0; j < n; j++) {
int prod = 1;
for (int k = 0; k < n; k++) {
for (int i = 0; i < m.size(); i++) prod *= m[i];
result[i][j] = (result[i][j] + A[i][k] * B[k][j]) % mod;
}
int result = 0;
}
for (int i = 0; i < m.size(); i++) {
}
int pp = prod / m[i];
return result;
result += a[i] * mod_inverse(pp, m[i]) * pp;
}
result %= prod;
}
vector<vector<long long>> mat_pow(vector<vector<long
return result;
long>>& A, int exp, int mod) {
}
int n = A.size();
// Fibonacci Numbers using Matrix Exponentiation
vector<vector<long long>> result(n, vector<long long>(n,
0));
vector<vector<int>> matrix_mult(vector<vector<int>> &A,
for (int i = 0; i < n; i++) result[i][i] = 1;
vector<vector<int>> &B) {
while (exp > 0) {
vector<vector<int>> C(2, vector<int>(2));
if (exp % 2 == 1) result = mat_mult(result, A, mod);
for (int i = 0; i < 2; i++) {
A = mat_mult(A, A, mod);
for (int j = 0; j < 2; j++) {
exp /= 2;
C[i][j] = 0;
}
for (int k = 0; k < 2; k++) {
return result;
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
return C;
}

vector<vector<int>> matrix_pow(vector<vector<int>> &A, int


n) {

You might also like