0x01——位运算

基础知识及二进制常见用法

  • 前言

bit是度量信息的单位,包含0和1两种状态。计算机的各种运算最后无不归结位一个个bit的变化。熟练掌握并利用位运算,能够帮助我们理解程序运行中的种种表现,提高程序循行的时空效率,降低编程复杂度。

  • 运算符优先级

从左到右优先级依次降低

加减移位比较大小位与异或位或
+,-<<,>><,>==,!=&xor(C++^)|
  • 位与memset

我们都知道,memset可以以字节为单位初始化变量或者数组,这里有几个特>别的数字:

  • 0x3F3F3F3F 1061109567
    -> 0x7F7F7F7F 2147483647
  • 0xFFFFFFFF -1

观察这几个数字,我们会发现0x3F3F3F3F是个很有用的数字,原因如下:

  • 可以直接用memset初始化
  • 0x3F3F3F3F的两倍不会超过int的最大范围
  • 这个数足够大

这也是常常使用INF = 0x3F3F3F3F的原因

memset(a,0x3f,sizeof a);
  • 移位运算
>><<
即除以2向下取整 1 < < n = 2 n , n < < 1 = 2 ∗ n 1<<n = 2^{n} , n<<1 = 2 * n 1<<n=2n,n<<1=2n

例题:

  1. a^b
  2. 64位整数乘法
  • 二进制状态压缩

二 进 制 状 态 压 缩 , 是 指 将 一 个 长 度 为 m 的 b o o l 数 组 用 一 个 m 位 的 二 进 制 整 数 表 示 {\color{Red} 二进制状态压缩,是指将一个长度为m的bool数组用一个m位的二进制整数表示} mboolm
并 储 存 的 方 法 。 利 用 下 列 位 运 算 操 作 可 以 实 现 原 b o o l 数 组 中 对 应 下 标 的 存 取 。 {\color{Red} 并储存的方法。利用下列位运算操作可以实现原bool数组中对应下标的存取。} bool

操作运算
取出整数n在二进制表示下的第k位 ( n > > k ) & 1 (n>>k)\&1 (n>>k)&1
取出整数n在二进制表示下的第0~k-1位(后k位) n & ( ( 1 < < k ) − 1 ) n\&((1<<k)-1) n&((1<<k)1)
把整数n在二进制表示下的第k位取反 n   x o r   ( 1 < < k ) n~xor~(1<<k) n xor (1<<k)
对整数n在二进制表示下的第k位赋值1 n n n| ( 1 < < k ) (1<<k) (1<<k)
对整数n在二进制表示下的第k位赋值0 n & ( n\&( n&(~ ( 1 < < k ) ) (1<<k)) (1<<k))

例题:

  1. 最短Hamilton路径
    2.起床困难综合症
  • 位的其他应用
  1. 成对变换

通过计算可以发现,对于非负整数 n : n: n:

  • 当 n 为 偶 数 时 , n   x o r   1 等 于 n + 1 当n为偶数时,n~xor~1等于n + 1 nn xor 1n+1
  • 当 n 为 奇 数 时 , n   x o r   1 等 于 n − 1 当n为奇数时,n~xor~1等于n - 1 nn xor 1n1

因 此 , “ 0 与 1 ” , “ 2 与 3 ” , “ 4 与 5 ” . . . 关 于 x o r 1 运 算 构 成 “ 成 对 变 换 ” 因此,“0与1”,“2与3”,“4与5”...关于xor1运算构成“成对变换” 012345...xor1

这一性质经常用于图论邻接表的储存。

在具有无向边(双向边)的图中把一对正反方向的边分别储存在邻接表数组的 n n n n + 1 n+1 n+1 位置(   n   ~n~  n 为偶数),就可以通过   x o r   1   ~xor~1~  xor 1 的运算获得与当前边   ( x , y )   ~(x,y)~  (x,y) 反向的边   ( y , x )   ~(y,x)~  (y,x) 的储存位置。详细应用我们将在讲解邻接表时(第0x13节)给出。

  1. lowbit运算

    lowbit运算定义非负整数   n   ~n~  n 在二进制表示下 “ 最 低 位 的 1 及 其 后 边 所 有 的 0   ” “最低位的1及其后边所有的0~” 10  构成的数值。例如 n = 10 的二进制表示为 ( 1010 ) 2 (1010)_{2} (1010)2,则 l o w b i t ( n ) = 2 = ( 10 ) 2 lowbit(n) = 2 = (10)_{2} lowbit(n)=2=(10)2。下面我们来推导   l o w b i t ( n )   ~lowbit(n)~  lowbit(n) 的公式。

    设 n > 0 ,   n   的 第   k   位 是   1 , 第 0 设n > 0 ,~n ~的 第 ~k ~位 是 ~1,第0 n>0, n  k  10 ~ k − 1 位 都 是 0 。 k - 1 位 都 是 0。 k10
    为 了 实 现   l o w b i t   运 算 , 先 把   n   取 反 , 此 时 第 0 为了实现~lowbit~运算,先把~n~取反,此时第0  lowbit  n 0
    ~ k − 1 位 都 是   1   。 k-1位都是~1~。 k1 1 
    在 令 n   =   n   +   1 , 此 时 因 为 进 位 , 第   k   位 变 为 1 , 在令n~=~n~+~1,此时因为进位,第~k~位变为1, n = n + 1 k 1
    第 0 第0 0 ~ k − 1 位 都 是 0 。 k - 1 位都是0。 k10
    而 且 n 的 第   k + 1   到 最 高 位 恰 好 与 原 来 相 反 , 所 以 而且n的第~k+1~到最高位恰好与原来相反,所以 n k+1 
    n & ( n\&( n&(~ n + 1 ) 仅 有 第 k 位 为 1 , n+1)仅有第k位为1, n+1)k1
    其 余 位 都 是 0 , 而 在 补 码 表 示 下 其余位都是0,而在补码表示下 0~ n   =   − 1 − n , 因 此 : n~=~-1-n,因此: n = 1n,
    l o w b i t ( n )   =   n & ( lowbit(n) ~=~n\&( lowbit(n) = n&(~ n + 1 )   =   n & ( − n ) n+1)~=~n\&(-n) n+1) = n&(n)

    l o w b i t   lowbit~ lowbit 操作可以配合Hash(0x14节)可以找到整数二进制表示下所有是1的位
    此外,   l o w b i t   ~lowbit~  lowbit 运算也是树状数组(0x42节)中的一个基本运算。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值