一、预备知识(补码,反码)

计算机通过二进制表示整形数,比如int型32位有符号整形数:
1表示为:0000…00001(共32位)
-1表示为:1111…1111(共32位)
补码计算法定义:非负数的补码是其原码本身;
负数的补码是其绝对值的原码最高位符号位不变,其它位取反,再加1。
表示原因:计算机逻辑运算没有减法,-1+1最高为溢出,剩余0000000000(32位)即为0;
则有a-b=a+b的(补码);
计算方式
-1表示原码为100…0001(32位),最高位位符号位。
-1的反码表示为:1111…110(32位),除符号位按位取反。
-1的补码表示为:1111…1111(32位),反码+1。
正数的补码为自己本身。
例子:
100的补码‭00000000000000000001100100‬
-30的补码 11111111111111111111111100010‬
100+(-30)=000000000000000000‭01000110‬
转换成10进制为70;

二、基本操作

1、按位与(&)

参加运算的两个数,换算为二进制(0、1)后,进行与运算。只有当相应位上的数都是1时,该位才取1,否则该为为0。

将10与-10进行按位与(&)运算:

0000 0000 0000 1010
1111 1111 1111 0110
0000 0000 0000 0010

所以:10 & -10 = 0000 0000 0000 0010
2、按位或(|)

参加运算的两个数,换算为二进制(0、1)后,进行或运算。只要相应位上存在1,那么该位就取1,均不为1,即为0。

将10与-10进行按位或(|)运算:

0000 0000 0000 1010
1111 1111 1111 0110
1111 1111 1111 1110

所以:10 | -10 = 1111 1111 1111 1110
3、按位异或(^)

参加运算的两个数,换算为二进制(0、1)后,进行异或运算。只有当相应位上的数字不相同时,该为才取1,若相同,即为0。

将10与-10进行按位异或(^)运算:

0000 0000 0000 1010
1111 1111 1111 0110
1111 1111 1111 1100

所以:10 ^ -10 = 1111 1111 1111 1100
可以看出,任何数与0异或,结果都是其本身。利用异或还可以实现一个很好的交换算法,用于交换两个数,算法如下:

a = a ^ b;
b = b ^ a;
a = a ^ b;

4、取反(~)

参加运算的两个数,换算为二进制(0、1)后,进行取反运算。每个位上都取相反值,1变成0,0变成1。
对10进行取反(~)运算:

0000 0000 0000 1010
1111 1111 1111 0101

所以:~10 = 1111 1111 1111 0101
5、左移(<<)

参加运算的两个数,换算为二进制(0、1)后,进行左移运算,用来将一个数各二进制位全部向左移动若干位。

对10左移2位(就相当于在右边加2个0):

0000 0000 0000 1010
0000 0000 0010 1000

所以:10 << 2 = 0000 0000 0010 1000 = 40
注意,观察可以发现,左移一位的结果就是原值乘2,左移两位的结果就是原值乘4。

6、右移(>>)

参加运算的两个数,换算为二进制(0、1)后,进行右移运算,用来将一个数各二进制位全部向右移动若干位。

对10右移2位(就相当于在左边加2个0):

0000 0000 0000 1010
0000 0000 0000 0010

所以:10 >> 2 = 0000 0000 0000 0010 = 2
注意,观察可以发现,右移一位的结果就是原值除2,左移两位的结果就是原值除4,注意哦,除了以后没有小数位的,都是取整。

三、延伸操作

1.快速幂(快速模幂)
①求a^b:

int pow(int a, int k)  { int ans = 1;while(k)  {if(k &1)  ans *= a;   //判断奇偶只用判断最后一位比取模快a *= a;k >>=1;     //比除法快多了}return ans;
}

②求a^b%p

int pow_mod(int a, int k,int mod)  { int ans = 1%mod;while(k)  {if(k &1)  ans =(long long) ans*a%mod;  //防止在对P取模前溢出a = (long long)a*a%mod;k >>=1;  //比除法快多了}return ans;}

例题:BZOJ1008
2.快速乘法
方法①

long long quickMul(long long a,long long b,long long mod)
{long long ans=0;while(b){if(b&1) ans=(ans+a)%mod;a=(a+a)%mod;  //(计算机加法比乘法快,a+a比a*2快)b>>=1;}return ans;
}

方法②:高效算法

long long quickMul(long long a,long long b,long long mod)
{a%=mod;b%=mod;long long  ans=0;while(b){if(b&1){ans+=a;if(ans>=mod)ans-=mod;}b>>=1;a<<=1;if(a>=mod)  a-=mod;}return ans;
}

方法③:使用long double优化版

long long quickMul(long long a,long long b,long long mod)
{a%=mod;b%=mod;long long c=(long double) a*b/mod;long long ans=a*b-c*mod;if(ans<0) ans+=mod;else if(ans>=mod) ans-=mod;return ans}

在这里仅提到部分操作,在ACM学习中,还有更多的操作可以用位运算。

疯子的算法总结(一) 位运算(快速幂、快速乘)相关推荐

  1. 算法之美 | 位运算的巧妙奥秘(一) | JAVA中位运算的深入浅出

    文章目录 前言 一.位运算符号 二.位运算的运算规则 扩展 前言 传智杯初赛后有感而写,我目前阶段所学习的算法,只是最基础的数学,对于数字和数学公式还是不敏感,在小卡与质数2那道题,解题的思路只有最基 ...

  2. 【牛客每日一题】4.16 逆序对 ( 数学 , 排列组合 ,快速幂 , 快速乘 )

    [每日一题]逆序对 链接:https://ac.nowcoder.com/acm/problem/14731 来源:牛客网 题目描述 求所有长度为n的01串中满足如下条件的二元组个数: 设第i位和第j ...

  3. 快速幂----快速求解底数的n次幂

    目录 一.快速幂 1.问题的引入 2.快速幂的介绍 3.核心思想 4.代码实现 二.Pow(x, n) 1.题目描述 2.问题分析 3.代码实现 三.猴子碰撞的方法数 1.题目描述 2.问题分析 3. ...

  4. java位运算求幂,程序员必学:快速幂算法

    前阵子,有小伙伴在我B站的算法教程底下留言 小伙伴们有任何疑问或者希望我解说任何内容,都可以在我的小我私家B站或民众号(xmg_mj)留言哦,我会尽我最大能力.只管抽时间去写文章\录视频来回应人人. ...

  5. 快速排序算法_基于位运算的快速排序算法

    前言 如果你准备看这篇文章,我就当你是懂快速排序算法原理的. 下面是我在2018年10月3日想到的基于二进制位运算对正整数进行的一种快速排序算法,目前的代码只能对正整数进行有效的排序,当然,稍微修改一 ...

  6. 【算法】 - 动态规划 + 位运算

    题目描述 思路1: 写一个返回2进制中1数量的函数countOne 遍历0到num,对每一个数使用countOne,并将结果保存到res中返回 var countBits = function (nu ...

  7. 【算法技巧】位运算装逼指南

    位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子.不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也 ...

  8. 疯子的算法总结(五) 矩阵乘法 (矩阵快速幂)

    学过线性代数的都知道矩阵的乘法,矩阵乘法条件第为一个矩阵的行数等与第二个矩阵的列数,乘法为第一个矩阵的第一行乘以第二个矩阵的第一列的对应元素的和作为结果矩阵的第一行第一列的元素.(详解参见线性代数) ...

  9. 算法之美 : 位运算

    上一小节我们用三道题了解一下面试过程中栈和队列的常见面试题.本小节笔者将通过几个 位运算 的题目来带大家熟悉下常用的位运算知识. 相比于栈和队列来讲,笔者自身认为位运算需要掌握的知识就要多一些,包括对 ...

最新文章

  1. 一个网卡设置多个IP作用
  2. ARM 内核移植中常见的错误
  3. DCMTK:演示状态查看器-后台打印程序
  4. VTK:Utilities之TimerLog
  5. 微信小程序的点击复制功能
  6. 论文浅尝 | 一种用于多关系问答的可解释推理网络
  7. SQL – 2.SQLServer的管理 + 3.SQL基础1 + 4.SQL基础2
  8. 阿里巴巴获评《福布斯》全球最有投资价值公司
  9. matlab dynprog,动态规划算法
  10. 编程之美——数字哑谜
  11. utf—8在苹果手机上乱码_Xcode下的中文乱码问题
  12. java中return finally_Java中return和finally到底哪个先执行
  13. 15 个实用的 PHP 正则表达式
  14. Scala文件内容生成本地文件
  15. Oracle TDE的数据加密示例并用logminer验证加密效果
  16. [个人小记]U盘文件超过4g怎么办?
  17. [推荐系统]互联网推荐系统比较研究
  18. Bochs、虚拟软盘与BootLoader
  19. 一日一技|Stata筛选出字符串中非数字的行
  20. LeetCode每日一题 1238.循环码排列

热门文章

  1. html元素data属性设置变量,HTML5 自定义属性 data-* 和 jQuery.data 详解
  2. 王小云计算机,王小云学者主页-科技工作者之家
  3. java -jar 找不到引用类_怎么解决java -jar找不到主类问题
  4. word椭圆形标注怎么设置_轻松应对毕业季,搞定论文图表,word中处理原来没你想象的那么难...
  5. 总结一些写毕业论文背景研究可以参考的资源
  6. 使用SpringBoot Admin监控SpringCloud微服务
  7. Python爬虫实战之(五)| 模拟登录wechat 1
  8. 深入Java集合学习系列:HashMap的实现原理
  9. Table definition on master and slave does not match
  10. android使用handler记录