前言:状态压缩是个很神奇的东西,可以把复杂的状态压缩到一个简单的数来保存。类似于哈希?当状态维数很多,但总量很少时,可以将状态压缩为一个数来记录。状态压缩常配dp,事实上配合别的算法也不错。
运算符:
按位与: & (全一则一,否则为零)
按位或: | (有一则一,否则为零)
按位取反: ~ (是零则一,是一则零)
按位异或: ^ (不同则一,相同则零)
左移位: << (a<<k==a*2k)
右移位: >> (a<<k==a/2k)
C++运算符优先级:
链接: link.
基本操作:
去掉最后一位 :(101101->10110) : x shr 1
在最后加一个0 :(101101->1011010) :x shl 1
在最后加一个1 :(101101->1011011) : x shl 1+1
把最后一位变成1 :(101100->101101) :x or 1
把最后一位变成0 :(101101->101100) : x or 1-1
最后一位取反 :(101101->101100) : x xor 1
把右数第k位变成1 : (101001->101101,k=3) : x or (1 shl (k-1))
把右数第k位变成0 :(101101->101001,k=3) : x and not (1 shl (k-1))
右数第k位取反 :(101001->101101,k=3) :x xor (1 shl (k-1))
取末k位 :(1101101->1101) : x and ((1<<k)-1)
取右数第k位 :(1101101->1,k=4) : x shr (k-1) and 1
把末k位变成1 : (101001->101111,k=4) : x or (1 shl k-1)
末k位取反 :(101001->100110,k=4) : x xor (1 shl k-1)
把右边连续的1变成0 : (100101111->100100000) : x and (x+1)
把右起第一个0变成1 : (100101111->100111111) : x or (x+1)
把右边连续的0变成1 :(11011000->11011111) : x or (x-1)
取右边连续的1 :(100101111->1111) : (x xor (x+1)) shr 1
去掉右起第一个1的左边 : (100101000->1000) | :x and not (x xor (x-1))(或 x and (-x))
把末尾最后一个0变为1:x | (x+1)
把k的二进制的高位1全部清空,只留下最低位的1:(x&-x)
减去最低位的1:x-(x&-x) = x^(x&-x)