• 算法竞赛进阶指南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)
     
  • 相关阅读:
    接口继承与归一化设计
    继承part1
    组合
    静态方法,小结
    类方法
    Java 集合各个接口特性
    PV操作示例详解
    什么是Java序列化,如何实现java序列化
    String简单知识点
    intValue()、parseInt()和valueOf
  • 原文地址:https://www.cnblogs.com/acm-cyz/p/11444722.html
Copyright © 2020-2023  润新知