得之我幸cyz

算法竞赛进阶指南0x01 位运算

补码:

补码和反码在负数表示中,绝对值相差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)
 

posted on 2019-09-02 15:57  生如夏花,死如秋叶  阅读(228)  评论(0编辑  收藏  举报

导航