算法 数论 位运算


一、位运算

位运算有6种,只能用于整型操作数。使用位运算不会改变原来的数。
优先级别由高到低依次为:按位取反( ~ ),移位(<<或>>),按位与( & ),按位异或( ^ ),按位或( | )。
注:只考虑正整数。

1.按位取反( ~ )
~ 是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变成0。

 ~ 0 = 1
 ~ 1 = 0

2.按位与(&)
&是二元操作符。当相应位上的数都是1时,该位取1,否则该为0。(有0取0,没0取1)

0 & 0 = 0     1 & 1 = 1
0 & 1 = 0     1 & 0 = 0 

3.按位异或( ∧ )
∧ 是二元操作符。当相应位置上的数相同,该位取0,如果不同该位取1。(不同为1,相同为0)

0 ^ 0 = 0   1 ^ 1 = 0
0 ^ 1 = 1   1 ^ 0 = 1 

4.按位或(|)
| 是二元操作符。只要相应位上存在1,那么该位就取1,如果都不为1,就为0。(有1取1,没1取0)

0 | 0 = 0     1 | 1 = 1
0 | 1 = 1     1 | 0 = 1     

5.左移 ( << )
将一个数二进制下的数向左移若干位,空出的位用0填充,并且丢弃移出左侧操作数末端的位。

n << k = n * (2 ^ k)

6.右移( >> )
将一个数在二进制下右移若干位,丢弃移出左侧操作数右端的位。使用0填充左端空出的位。

n >> k == n / (2 ^ k)

二、位运算技巧

1.基础技巧

x & 1             判断奇偶
(x >> k) & 1      判断二进制 x 的第k位是 1 还是 0   
x & (1 << k)      判断二进制 x 的第k位是 1 还是 0  
-x = ~x+1         负数是原码取反+1

2.lowbit( x ) ,用于计算 x 的二进制表示中最低位 1 的大小

int lowbit(int x){
	return x & (- x);
}

3.消除x的最后一位一

x = x & (x-1)         

三、异或

1.运算法则

交换律: a ^ b = b ^ a
结合律: a ^ b ^ c = a ^ (b ^ c)
自反:   b = a ^ b ^ a
若 d = a ^ b ^ c 可以推出 a = d ^ b ^ c

按位异或特点:

x ^ 0 = x          0异或任何数等于任何数
x ^ x = 0          任何数异或自己等于 0(可以判断两个值是否相等)
x ^ (1 << k)       使某些特定的位翻转
n ^ 1 = n + 1      当 n 为偶数时
n ^ 1 = n - 1      当 n 为奇数时   

四、STL bitset

1.bitset 概念
bitset 可看作一个多位二进制数,每8位占用1个字节,相当于采用了状态压缩的二进制数组,并支持基本的位运算。

在估算程序运行的时间时,一般以32位整数的运算次数为基准,因此 n 位bitset执行一次位运算的复杂度可视为n/32,效率较高。
注:头文件 #include< bitset >

2.位运算操作符

bitset<n> s      表示一个n位二进制数
~ s             返回对s按位取反的结果。
&,|,^           返回对两个位数相同的bitset执行按位与、或、异或运算的结果
>>,<<           返回把个bitset右移、左移若干位的结果。
==, !=          比较两个bitset代表的二进制数是否相等。

3.基本操作

s.count()            返回有多少位为1。
any/none             若s所有位都为0,则s.any()返回false, s.none()返回true.
                     若s至少一位为1,则s.any()返回true , s.none()返回false.
s.set()              把s所有位变为1
s.set(i,k)           把s的第i位改为k,即s[i]=k
s.reset()            把s所有位变为0
s.reset(i,k)         把s的第i位改为0,即s[k]=0。
s.flip()             把s的所有位取反,即s=~s
s.flip(k)            把s的第k位取反,即s[k]^=1
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值