BIT Manipulation
BITMASK - Two varieties of approach
- Type -1 --> analyze for each bit (for simplicity -> take array as {1 0 0 1 0} types)
- Practice ke liye => OA wala question + Atcoder
- Type-2 (See both accepted solutions)
BITSET in cpp
- NOTE - use bitset => binary representation (NOT decimal)
- Why do we need?
- Let's say make boolean array of size 1e9 => High time complexity
- But with bitset, it will automatically break 1e9 into multiple part of each 32 size (bcz 32-bit system) => time = 1e9/32
- Can use in case of take/ not take situation
- bitset<1000> num --> by default, num = 0
- bitset<1000> num (x) --> set num = x => x can be number or binary string
- num.to_string() => converts to string
- num.to_ullong() => converts to unsigned long long;
- can access ith bit as num[i]
- Operations
-> num.flip(2) - flip 2nd indexsets all bits to 1 --> num.set() sets all bits to 0 toggles the values of bits -> num.flip() - flip all returns the number of bits = 1 --> can't use __builtin_popcount(x)
These can be done in O(1) like &, |, ^ --> NOT O(logn)
__builtin_popcountll(x) --> counts the number of 1 in x
__builtin_popcountll(x) --> counts the number of 1 in x
__builtin_ctz(x) --> counts the number of trailing zeros in x
- n & (n+1) clears all trailing ones:
make all trailing 1 before 1st '0' as 0 - 00110111 -> 00110000 => makes all 1 before 1st '0' as 0
- n | (n+1) sets the last cleared bit:
make 1st 0 as 1 and no change to others - 00110111 -> 00111111
m & (m-1)unset the last --> Eg.- m=26 as 11010 changes into 11000- if n is in form of 2^m => (n-1) & n = 0
- if odd => n&1 = 1
- To check bit at index = i --> 1 & (num>>i ) --> gives only 0 or 1
- AVOID (1<<i) & num --> bcz this results in 0 or 2^i
- To set bit at index = i --> num | (1<<i )
- To toggle bit at index = i --> num ^ (1<<i )
- ~num => 1's complement --> invert all bits
- ~num + 1 --> 2's complement => same as -num
- bcz in cpp all -ve are stored as 2's complement
- a+b = (a^b) + 2*(a&b)
- Just like full adder in digital system => sum = a xor b
- Carry = a&b --> BUT why 2*(a&b)
- bcz a&b just tells the places where we have carry
- let's say 1+1 (in bit form) --> gives 10 (i.e. 2 in decimal form)
- This 2 is the actual value => val*places or 2*(a&b)
- NOTE: - (a+b) and (a^b) have same parity
Repeats in cycle as previous value used to generate next value --> 4n bcz it's last 2 characters are 0 => no effect on addding 1, 2 or 3


Comments
Post a Comment