关于lowbit运算的相关知识

本篇随笔简单讲解一下计算机中位运算的一类重要运算方式——\(lowbit\)运算。

lowbit的概念

我们知道,任何一个正整数都可以被表示成一个二进制数。如:

\[(2)_{10}=(10)_2
\]

\[(4)_{10}=(100)_2
\]

\[\cdots
\]

那么定义一个函数\(f=lowbit(x)\),这个函数的值是\(x\)的二进制表达式中最低位的\(1\)所对应的值。

比如:

\[(6)_{10}=(110)_2
\]

那么\(lowbit(6)\)就等于\(2\),因为\((110)_2\)中最低位(就是从右往左数的第二位)对应的数是\(2^1=2\)

所以假设一个数的二进制最低位的\(1\)在从右往左数的第\(k\)位,那么它的\(lowbit\)值就是

\[2^{k-1}
\]

lowbit函数的实现

lowbit函数实现有两种方式:

一、

x&(x^(x-1))

二、

x&-x

简单解释一下:

我们得到lowbit的值,只需要得到最后一个1的位置,并且把除了这个位置之外的所有位置全部置成零。然后输出就可以。

那么我们看一看x&(x^(x-1))

拿上面的6举例:

\[(110)_2-1=(101)_2
\]

我们发现,根据小学数学减法运算的借位原则(滑稽),对一个二进制数进行减1,那么会出现从这个这个数的最后一个1开始到最后的所有数都取反,即构成一个\(01111\cdots\)的串。

我们把这个数与原数异或,就会造成:第一个1以后的数(包括第一个1)全部取1.其他的位全部取0.即构成一个由一堆0后面跟一堆1的串。

那么再把原式做一个与运算,那么除了原来的那个1(对应位都是1)为1,其他位全是0,完成任务。

那么我们再看一看x&-x

根据计算机补码的性质。

补码就是原码的反码加一

如:

\[(110)_2=6
\]

反码:

\[(001)_2
\]

加一:

\[(010)_2
\]

可以发现变为反码后 x 与反码数字位每一位都不同, 所以当反码加1后神奇的事情发生了,反码会逢1一直进位直到遇到0,且这个0变成了1,所以这个数最后面构造了一个 100… 串。 由于是反码,进位之后由于1的作用使进位的部分全部取反及与原码相同,所以可以发现 lowbit 以前的部分 x 与其补码即 -x 相反, lowbit x 与 -x 都是1,lowbit 以后 x 与 -x 都是0 所以 x&-x 后除了 lowbit 位是1,其余位都是0。符合条件。

用lowbit运算统计1的个数

我们可以使用lowbit运算统计一个整数的二进制形式下1的个数。

实现原理很简单啦,就是:我们先用lowbit运算找出\(lowbit(x)\),然后用原数减去这个数,依次循环,直到为0为止。

这也是树状数组的实现原理。

代码:

while(x)
{
x-=x&-x;
ans++;
}

(巨短无比)

lowbit运算的应用

关于lowbit运算,最著名的应用应该算是树状数组。但是lowbit的神妙远远不止树状数组,在很多二进制和位运算的相关题目中,都有lowbit运算的影子。甚至,在状态压缩DP中,lowbit也扮演着一份不可忽视的角色。

浅谈lowbit运算的更多相关文章

  1. 浅谈JavaScript浮点数及其运算

    原文:浅谈JavaScript浮点数及其运算     JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...

  2. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  3. 浅谈DES加密算法

    一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节 ...

  4. 浅谈Base64编码算法

    一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...

  5. 【转】 浅谈Radius协议

    浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报  分类: Radius协议分析(6)  从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...

  6. 转:浅谈Radius协议 -来自CSDN:http://blog.csdn.net/wangpengqi/article/details/17097221

    浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报  分类: Radius协议分析(6)  从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...

  7. 转:浅谈C/C++中的指针和数组(一)

    再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...

  8. 浅谈线程池(中):独立线程池的作用及IO线程池

    原文地址:http://blog.zhaojie.me/2009/07/thread-pool-2-dedicate-pool-and-io-pool.html 在上一篇文章中,我们简单讨论了线程池的 ...

  9. 转载 浅谈C/C++中的static和extern关键字

    浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T   static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...

随机推荐

  1. redis在centos7下安装(源码编译)

    下载 地址:http://www.redis.cn/download.html 下载稳定版本 把安装包上传到服务器 linux下安装 解压 进入解压后的目录,编译 创建目录,安装并指定目录 修改配置 ...

  2. 【Oracle】SQL的一些关键字

    1. distinct 关键词 DISTINCT 用于返回唯一不同的值: 只可以在select中使用: 既可以对一列,也可以对多列使用: distinct对NULL是不进行过滤的,即返回的结果中是包含 ...

  3. DirectShow 应用开发过程

    本文准备总结一些 Direct Show 常用的API接口函数,方便以后查询回忆.如果这里没有你想了解的函数,你可以自行搜索MSDN + 函数名去 MSDN 查找你想要了解的函数,也可以查看百度百科相 ...

  4. git分支合并创建切换

    1. 场景描述 介绍下Git最新内容合并到主干.从主干创建最新分支.idea下切换最新分支,能在2分钟内完成git合并.分支创建以及在idea中完成切换,希望能帮到一些朋友. 2. 解决方案 从以下三 ...

  5. PHP7.1.X+wordpress+windows,安装Memcached服务

    1.下载安装Memcached 64位系统1.4.4版本:memcached-win64-1.4.4-14.zip 2.解压缩在任意盘符,然后进入文件夹,在文件夹中运行CMD输入以下命令: 1)输入 ...

  6. antV G2 为柱状图添加背景颜色

    工作中需要在基础柱状图的基础上添加一个自定义高度的背景颜色, 基础柱状图: 目标柱状图: 由于chart绘图可以重叠,通过该特性,我们可以在画两次图重叠在一起,第一次绘图描述背景,第二次绘图描述数据, ...

  7. CENTOS 7 内网网段在用IP地址检测Shell脚本优化版

    脚本内容 #!/bin/bash ############################################################################# # 用途: ...

  8. IIS 上部署 ASP.NET Core 应用程序

    1.下载 .Net Core Runtime 和 Hosting Bundle 下载地址:https://dotnet.microsoft.com/download/dotnet-core 分别下载 ...

  9. 从程序集加载类型,遇到 ReflectionTypeLoadException 的处理办法

    处理办法 catch ReflectionTypeLoadException ,然后从里面读取 Types 数据(成功加载的类型)就可以了. 参考 ReflectionTypeLoadExceptio ...

  10. excel 知识备忘

    public void UpdateShapesColor(string value) { foreach (Microsoft.Office.Interop.Excel.Shape chart in ...