位运算详解

0*01 位运算

补码

  • 在补码下每个数值都有唯一的表示方式
  • 发生算数溢出时,32位无符号整数相当于自动对2^32取模
  • 0*3F 3F 3F 3F 满足一下两个条件
    • 整数的两倍不超过int能表示的最大整数
    • 整数的每个字节都是相同的

移位运算

左移

​ 在二进制下把数字同时向左移动,低位以0填充,高位越界后舍弃
1 < < n = 2 n , n < < 1 = 2 n 1<<n=2^n, n<<1=2n 1<<n=2n,n<<1=2n

右移

​ 在二进制下把数字同时向右移动,高位以符号位填充,低位越界后舍弃
n > > 1 = F l o o r ( n / 2.0 ) n>>1=Floor(n/2.0) n>>1=Floor(n/2.0)

例题

  1. 求ab%p的值,1<=a,b,p<=109

    枚举二进制下每位,没了……

    #include<bits/stdc++.h>//a^b%p
    
    using namespace std;
    int a,b,p;
    int power(){    
        int ans=1%p;
        for(;b;b>>=1){  //取遍所有数位
            if(b&1) ans=(long long)ans*a%p; //取当前最后一位
            a=(long long)a*a%p;
        }
        return ans;
    }
    int main(){
        scanf("%d%d%d",&a,&b,&p);
        printf("%d",power());
        return 0;
    }
    
  2. 求a*b%p的值,1<=a,b,p<=10^18

    更神奇的算法……时间复杂度O(n)

    #include<bits/stdc++.h> //时间复杂度O(n)的神奇算法  a*b%p
    using namespace std;
    typedef unsigned long long ull;
    ull a,b,p;
    ull mul(){
        a%=p,b%=p;
        ull c=(long double)a*b/p;
        ull x=a*b,y=c*p;
        long long ans=(long long)(x%p)-(long long )(y%p );
        if(ans<0)   ans+=p;
        return ans;
    }
    int main(){
        scanf("%lld %lld %lld",&a,&b,&p);
        printf("%lld",mul());
        return 0;
    }
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值