【阅读笔记】0x01 位运算

1.补码表示: ~x=-1-x

2.自然溢出:unsigned long long 自动对2^32取模,可以用来hash

3.基本位运算操作:

左移:1<<n=2^n

n<<1=2n,n<<2=4n,n<<3=8n。。。

算术右移:n>>1=n/2 ,n>>4=n/16。。。算术右移=除以2向下取整 e.g. (-3) >> 1 = -2,3>>1=1

P.S. 整数/2 = 除以2向0取整 e.g. (-3)/2=-1 , 3/2=1

tips:以下二进制以0为最低位,即k从0开始。

取出整数n在二进制下的第k位:(n>>k)&1

取出整数n在二进制下的第0~k-1位(后k位):n&((1<<k)-1)

把整数n在二进制表示下的第k位取反:n^(1<<k)

把整数n在二进制表示下的第k位赋值为1:n|(1<<k)

把整数n在二进制表示下的第k位赋值为0:n&(~(1<<k))

以上常用于把一个n维bool数组压缩成一个n维二进制整数,即状态压缩,常用于状压DP

注意符号的运算优先级:加减(+ -)>移位(>> <<)>比较大小(> < == !=)>位与(&)>异或(^)>位或(|)

可以直接每个运算符都加一个括号来提高正确性。

成对变换:n为偶数 n^1=n+1 ; n为奇数 n^1=n-1 so“0 1”,“2 3”构成成对变换,常用于存图中的边与其反向边。

lowbit: lowbit(x)=x&-x 返回x在二进制表示下的最低位的1及其后面的0构成的数值。是树状数组的核心。

4.快速幂 O(logn)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
    ll a,b,p;
    scanf("%lld%lld%lld",&a,&b,&p);
    ll mul=1;
    for(;b;b>>=1){
        if(b&1) mul=(mul*a)%p;
        a=(a*a)%p;
    }
    printf("%lld",mul%p);
    return 0;
}

5.64位整数乘法 O(logn)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
    ll a,b,p;
    scanf("%lld%lld%lld",&a,&b,&p);
    ll mul=0;
    for(;b;b>>=1){
        if(b&1) mul=(mul+a)%p;
        a=(a*2)%p;
    }
    printf("%lld",mul%p);
    return 0;
}

 

 

 

转载于:https://www.cnblogs.com/Loi-Brilliant/p/9417598.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值