位运算食用指南

位运算

位运算是啥?在了解位运算之前,我们要先学习一个预备知识——二进制。因为位运算是在二进制的基础上产生的。

二进制

俗话说“温故而知新,可以为师矣。” 在学习二进制之前,我们需要温习一下我们幼稚园就学到的十进制(逃。
十进制:顾名思义——满十进一。应用广泛,尤其是在幼稚园以后的生活中,无论是我们买菜还是造核武器,无论是刷高考题还是搞科研。只要有计算的地方, 80 % 80\% 80% 都离不开十进制的运算。所以“一生二,二生三,三生万物。”并不是没有道理的(雾。

那么这又跟二进制有什么关系呢?看到了十进制的“慨念”,我们不难 y y yy yy 出二进制就是满二进一。**(好像跟生活没有太大的关系啊!)**二进制的应用主要体现在我们面前的计算机中,全世界的人都知道计算机只用一堆长长的 01 01 01 串构成的。
那么作为一个“ O I e r OIer OIer ”我们就要搞清楚二进制到底是什么!

二进制与十进制转化

(请自行百度) o r or or 翻部分地区的教材(作者上学的时候是从人教版必修3(新课标版)上学到的)

二进制中一些基础的运算(位运算)

位运算的实质是将参与运算的数字转化为二进制,然后进行按位运算。

按位与(&)

运算两位全为 1 1 1 ,结果为 1 1 1 。即 1 1 1 & 1 = 0 , 1 1 = 0, 1 1=0,1 & 0 = 0 , 0 0 = 0, 0 0=0,0 & 1 = 0 , 0 1 = 0, 0 1=0,0 & 0 = 0 0 = 0 0=0
例如 51 51 51 & 5 − > 00110011 5 -> 00110011 5>00110011 & 00000101 = 00000001 − > 51 00000101 = 00000001 -> 51 00000101=00000001>51 & 5 = 1 5 = 1 5=1

特殊用法:

  1. 0 0 0 相与可清零。
  2. 1 1 1 相与可保留原值,可从一个数中取某些位。例如需要取 10101110 10101110 10101110 中的低四位, 10101110 10101110 10101110 & 00001111 = 00001110 00001111 = 00001110 00001111=00001110,即得到所需结果。

按位或(|)

运算两位只要有一位为 1 1 1 ,其结果全为 1 1 1 。即 1 ∣ 1 = 1 , 1 ∣ 0 = 1 , 0 ∣ 1 = 1 , 0 ∣ 0 = 0 1 | 1 = 1, 1 | 0 = 1, 0 | 1 = 1, 0 | 0 = 0 11=1,10=1,01=1,00=0

特殊用法:

  1. 0 0 0 相或可保留原值。
  2. 1 1 1 相或可将对应位置变为 1 1 1 。例如,将 X = 10100000 X = 10100000 X=10100000 的低四位置 1 1 1 ,使 X ∣ 00001111 = 10101111 X | 00001111 = 10101111 X00001111=10101111 即可。

异或运算(^ o r or or X O R XOR XOR

(作者认为就是一个不进位的加法运算)
两位为“异”,即一位为 1 1 1 一位为 0 0 0 ,则结果为 1 1 1 ,否则为 0 0 0 。即 1 1 1 ^ 1 = 0 , 1 1 = 0, 1 1=0,1 ^ 0 = 1 , 0 0 = 1, 0 0=1,0 ^ 1 = 1 , 0 1 = 1, 0 1=1,0 ^ 0 = 0 0 = 0 0=0

特殊用法:

  1. 使指定位翻转:找一个数,对应 X X X 要翻转的各位为 1 1 1 ,其余为 0 0 0 ,使其与 X X X 进行异或运算即可。例如, X = 10101110 X=10101110 X=10101110 ,使低四位翻转, X X X ^ 00001111 = 10100001 00001111 = 10100001 00001111=10100001
  2. 与0相异或保留原值。例如 X X X ^ 00000000 = 10101110 00000000 = 10101110 00000000=10101110
  3. 换两变量的值。(比借助容器法、加减法效率高)原理:一个数对同一个数连续两次进行异或运算,结果与这个数相等。因此,交换方法为: A = A A = A A=A ^ B , B = A B, B = A B,B=A ^ B , A = A B, A = A B,A=A ^ B B B

去反(~)

将一个数按位取反,即 ~ 0 = 1 , 0 = 1, 0=1, ~ 1 = 0 1 = 0 1=0

左移( &lt; &lt; &lt;&lt; <<

作者现在用到的就是 &lt; &lt; 1 &lt;&lt; 1 <<1 等价于将数字乘以 2 , &lt; &lt; 2 2, &lt;&lt; 2 2,<<2 等价于乘以 4 4 4

左移( &gt; &gt; &gt;&gt; >>

既然 &lt; &lt; 1 &lt;&lt; 1 <<1 是乘以 2 2 2 ,那么 &gt; &gt; 1 &gt;&gt; 1 >>1 就是除以2。以此类推。

这样写代码会使自己代码的 B B B 格++,For Example(segment - tree):

const int maxn = 100010;

struct segmentree {
	ll val, tag;
}st[maxn<<2];

inline void up(int p) {
	st[p].val = st[p<<1].val + st[p<<1|1].val;
	return ;
}
//p<<1 表示的是p的左儿子,p<<1|1 表示的是p的右儿子。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值