YOU CAN DRINK ALL YOU LIKE, BUT IN THE MORNING YOU GET HEADACHE WITH THE SAME PROBLEMS.
0x01 位 运 算
基础知识
用
xor
表示异或运算,在m
位二进制数中,通常称最低位为0
位,从右到左依此类推,最高位为m-1
位。|-1|
的原码为00000001
|-1|
的反码为11111110
-1
的补码为11111111
,十六进制表示为0xff
8
位二进制对应的最大值127
的十六进制表示为0x7f
在计算机中数字以其补码的形式保存,正数的补码等于其原码,负数的补码等于其对应正数的原码取反码再+1
对于
32
位二进制数C
(设十进制的值为S
),其按位取反得到的编码~C
对应的十进制的值为-1-S
(正负都满足此规律)补码下每个数值都有唯一的表示方式,并且任意两个数值做加减法运算,都等价于在
32
位补码下做最高位不进位的二进制加减法运算。发生算术溢出时,32
位无符号整数相当于自动对2^32
取模,这也解释了有符号整数溢出时为何会出现负数的现象。在算法竞赛中常用十六进制来表示一个常数,这样书写需要八个字符。
10进制 16进制 21 4748 3647 0x7f ff ff ff 10 6110 9567 0x3f 3f 3f 3f -1 0xff ff ff ff 4
个字节的int
表示的最大值为21 4748 3647
4
个字节的unsigned int
表示的最大值为42 9496 7295
0x3f 3f 3f 3f
是一个很有用的值,它满足两个条件:
其一,整数的两倍不超过int能表示的最大正整数
其二,二进制下每八位都相同
因此,我们可以用memset(a, 0x3f, sizeof a)
来给a
数组的每一个元素都赋值为正无穷,虽然0x7f
能给每一个元素赋值成最大,但是为了避免溢出情况,推荐用0x3f
。1 << n = 2^n, n << 1 = 2n
n >> 1 = n / 2.0 向下取整
需要注意的是,整数做/
运算执行的是向0
取整(-3) >> 1 = -2, (-3) / 2 = -1
除非特殊提示,我们默认右移采用的是算术右移的实现方式
逻辑右移不考虑符号位,右移一位,左边补零即可。
算术右移考虑符号位,右移一位,若符号位为1,就在左边补1;否则,就补0。
所以算术右移也可以进行有符号位的除法,右移n位就等于除2的n次方。
例如,8位二进制数11001101分别右移一位。
逻辑右移就是[0]1100110
算术右移就是[1]1100110
状态压缩
二进制状态压缩是指将一个长度为m
的bool
数组用一个m
位二进制整数表示并存储的方法,利用如下操作实现对原bool
数组对应下标元素的存取。
- 取出整数
n
的第k
位:(n>>k)&1
- 取出整数
n
的后k
位(0到k-1位)
:((1<
- 把整数
n
的第k
位反转:(1<
- 把整数
n
的第k
位赋值为1
:(1<
- 把整数
n
的第k
位赋值为0
:(~(1<
当m
不大时,我们可以使用一个整数存储,当m很大时,我们可以用若干个整数存储(int数组)
,也可以用C++STL
为我们提供的bitset
实现。
成对变换
通过计算可发现,对于非负整数n
:
- 当
n
为偶数时,n xor 1 = n + 1
- 当
n
为奇数时,n xor 1 = n - 1
因此0与1
, 2与3
, 4与5
... 关于xor 1
运算构成成对变换。
这一性质经常用于图论邻接表中边集的存储。在具有无向边(双向边)的图中把一对正反方向的边分别存储在邻接表数组的第n
与n+1
位置(其中n
为偶数),就可以通过xor 1
的运算获得与当前边(x,y)
反向的边(y,x)
的存储位置。
lowbit运算
lowbit(n)
定义为非负整数n
在二进制表示下“最低位的1及其后边所有的0”构成的数值。
例子:lowbit(10)=2
其原理为:lowbit(n)=n&(~n-1)=n&(-n)
lowbit
运算配合Hash
可以找出整数二进制下所有是1
的位,所花费的时间与1
的个数同级。为了达到这个目的,我们只需要不断把n
赋值为n-lowbit(n)
直至n=0
。我们可以把每次减去的数(其一定为2的幂)求log
得到对应的1
所在的位数,因为C++math.h
库中的log
函数复杂度常数较大,所以我们可以预处理一个数组,通过Hash
的方法代替log
运算。
此外lowbit
运算也是树状数组中的一个基本运算。
![ac0e11fdab0f5a3864474152799531e2.png](https://img-blog.csdnimg.cn/img_convert/ac0e11fdab0f5a3864474152799531e2.png)
![b78a1723c4b364c09d9bfd8e5d1d684d.png](https://img-blog.csdnimg.cn/img_convert/b78a1723c4b364c09d9bfd8e5d1d684d.png)