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

Bitwise Operators_

Uploaded by

chayon das
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Bitwise Operators_

Uploaded by

chayon das
Copyright
© © All Rights Reserved
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