补码:
补码和反码在负数表示中,绝对值相差1
unsigned int 表示32位无符号整数
0x3f 3f 3f 3f 表示一个很大的数
移位运算:
左移:<<1,相当于除以2,地位以0填充,高位越界后舍弃,但它比/2要快
算术右移:在二进制补码表示下把数字同时向右移动,高位以符号位填充,低位越界后舍弃,n>>1=除以2向下取整
整数/2:在c++中实现位“除以2向0取整”,(-3)/2=-1,3/2=1
逻辑右移:在二进制补码表示下把数字同时向右移动,高位以0填充,地位越界后舍弃
快速幂:
1 int power(int a,int b,int p)///calculate(a^b) mod p 2 { 3 int ans=1%p; 4 for(;b;b>>=1) 5 { 6 if(b&1) 7 { 8 ans=(long long )ans*a%p; 9 } 10 a=(long long )a*a%p; 11 } 12 return ans; 13 }
最后返回的ans是int型的,时间复杂度是O(log2 b)
1 long long mul(long long a,long long b,long long p) 2 {///计算a*b mod p 3 long long ans=0; 4 for(;b;b>>=1) 5 { 6 if(b&1) 7 ans=(ans+a)%p; 8 a=a*2%p; 9 } 10 return ans; 11 }
这个最后返回的是long long,用来快速计算a*b mod p,时间复杂度是O(log2 b)
二进制状态压缩
二进制状态压缩是指将一个长度位m的bool数组用一个m位的二进制整数表示并存储的方法。利用下列位运算操作可以实现原bool数组中对应下标元素的存取
取出整数n在二进制表示下的第k位:(n>>k)&1
取出整数n在二进制表示下的第0~k-1位(后k位):n&((1<<k)-1)
把整数n在二进制表示下的第k位取反:n xor (1<<k)
对整数n在二进制表示下的第k位赋值1:n|(1<<k)
对整数n在二进制表示下的第k位赋值0:n&(~(1<<k))
一些运算的优先级:
加减 > 移位 > 比较大小 > 位与 > 异或 > 位或
+、- <<,>> >,<,==,!= & xor(c++ ^) |
成对变换
对于非负整数:
当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 构成的数值。例如n=10的二进制表示为1010,则lowbit(N)=2=10(2)
lowbit(n)=n&(-n+1)=n&(-n)