首页 > 编程语言 >(坚持每天写算法)算法学习与复习part1基础算法1-13——位运算

(坚持每天写算法)算法学习与复习part1基础算法1-13——位运算

时间:2024-02-03 12:44:07浏览次数:31  
标签:13 运算 二进制 int lowbit 数值 part1 算法 include

  最近确实有在写算法,在写dp,之前学的时候不全,被计数,树型等dp折磨了一下。

  位运算是将重点放在数字的位上,通常作为辅助行动,比如状态dp,有的时候是为了节省时空复杂度而使用的。

  这是今天的题目:

   位运算应用的情况除了上面讲的,还有单纯的位问题,上面的题目就是一个例子。

  这道题的思路运用到了一个lowbit运算,lowbit运算是获取一个二进制数中最右边的1所对应的数值(十进制),例如,对于二进制数101100(十进制数为44),它的lowbit为100(十进制数为4)。这是因为最右边的1所对应的位是第三位,对应的数值为4,因此lowbit(x) = 4。

  lowbit运算有一个公式:lowbit(x) = x & (-x)

  lowbit的原理,说真的我不是很在意它的原理,因为这种感觉是结果(或者说是规律)比较重要一点,不过这里还是贴出大佬的解释:

  1.对于x的二进制表示中,k位之右的数,它们在x中都对应了0,所以对于这部分的数值,x & (-x) = 0。
  2.对于x的二进制表示中,k之左的数值,它们在x中对应了0 或者 1,而在-x的二进制表示中,他们对应 1 或 0, 与 x 的数值相反(0对1, 1对0)。因此,在进行按位与运算时,x中第k位之左的数值能够与-x中的相应位数值得到0。
  3.对于第 k 位来说,x 的第k位为1,-x的第k为也为1,因此,在进行按位与运算时,x中第k位的数值能够与-x中的第k为数值得到1。
  4.因此 x & (-x) = 2^k

  当知道了lowbit运算后,这道题也很容易写了,计算到最后面的1后将它消除掉,这样子最后面的1就会变成前面的1,就可以计算了。

  这里是c++代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int main(){
    int n;
    int data;
    cin >> n;
    
    while(n --){
        int s = 0;
        cin >> data;
        for(int i = data ;i ; i -= i & -i) s ++;
        cout << s << " " ;
    }
}

  这里是我的打卡代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
//下意识直接使用了数组,看了一下题解改了一下
using namespace std;

//y总说的 i & (-i) == i & (~i + 1),其实个人觉得很奇怪,假设i是0000 0011(3),正数的反码是他本身,再加1,那么应该是0000 0100,是4,而不是1011(-3)
        //或者是(以原码的角度来看是)也不是1110(-3)(其实应该按照八位来算,但是只要是负数,那么首位就是1,那也不符合

        //负数的话,11111111是-1,除了符号位都取反,再加1,算出来其实是100000001,补码的角度来看也不是1.
        //计算机中的,都是按照补码来存储的吧,至少C++应该是

        //唯一的解释是,这个取反号,不分谁是符号位,而是直接全部取反,不要再思考什么“正数的反码是他本身”,他这个号就是一视同仁
        //按这样想,负整数的都是成立的()(注意,数的表示都是按照补码)
        //很玄乎,减去lowbit操作后面就可以知道i的个数了,个人表示这是不是就是一种规律呢
        //怎么当时傻傻的,减去lowbit操作就可以知道i的个数,原因可以用二进制减一下就知道了。
        //https://zhuanlan.zhihu.com/p/118432554


int main(){
    int n;
    cin >> n;
    while(n --){
        int x , s=0;
        cin >> x;

        for(int i = x ; i ;i -= i & -i ) s ++;
        //建议背一下模板

        cout << s  <<" ";
    }
    return 0;
}

  参考链接:https://zhuanlan.zhihu.com/p/118432554

        AcWing 801. 二进制中1的个数--海绵宝宝 - AcWing

 

标签:13,运算,二进制,int,lowbit,数值,part1,算法,include
From: https://www.cnblogs.com/clina/p/18004540

相关文章

  • 【优先级调度算法:抢占式与非抢占式】
    (文章目录)前言在操作系统中,进程调度决定了哪个进程应该获得CPU的使用权,以便能够执行。而优先级调度算法就是其中之一,它通过为每个进程分配一个优先级来决定进程的执行顺序。什么是优先级调度算法?优先级调度算法是一种用于确定哪个进程将在CPU上执行的方法。每个进程都会被分配......
  • 20240130-DP以及优化随记
    状态转移方程递归关系(从已知求得未知的表达式)背包dp0-1背包,多重,完全,混合模版套用//多重背包#include<bits/stdc++.h>usingnamespacestd;constintN=507,M=1e5+7;intp,n,x,y,z,dp[10005];intmain(){ cin>>p>>n; for(inti=1;i<=n;i++){ scanf("%d%d......
  • 第十五节:排序算法详解3(希尔排序、计数排序、桶排序、基数排序)
    一.        二.        三.         !作       者:Yaopengfei(姚鹏飞)博客地址:http://www.cnblogs.com/yaopengfei/声     明1:如有错误,欢迎讨论,请勿谩骂^_^。声     明2:原创博客请在转载......
  • 算法学习
    今天学习了约数的个数怎么求,一般的算法会超时。这时我们需要用到一个定理:p=[n/i]:表示在[1,n]的区间内,有约数i的个数为p个。所以这时,在求约数个数的问题上,我们只需要遍历[1,n],设置一个计数器即可。当n很大时,跨越太大,这时i++、就会很慢,设置j=n/(n/i)+1;下一次让i=j;这样跨度较......
  • 基础模板/算法
    线性筛求素数#include<bits/stdc++.h>usingnamespacestd;constintN=5e7+50;intn,tot,prime[N];//prime存储所有素数boolflag[N];//判断是否为素数intmain(){scanf("%d",&n);//初始化,flag全部置为truefor(inti=1;i<=n;i++)fl......
  • Python数据结构与算法03-单循环链表
    单循环链表classListNode:def__init__(self,val,next=None):self.val=valself.next=nextclassSingleLoopLinkList:def__init__(self,node=None):self.__head=nodeifnode:#如果不是空链表node.next=node......
  • 【洛谷 P2249】【深基13.例1】查找(向量+lower_bound)
    【深基13.例1】查找题目描述输入个不超过的单调不减的(就是后面的数字不小于前面的数字)非负整数,然后进行次询问。对于每次询问,给出一个整数,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出。输入格式第一行个整数和,表示数字个数和询问次数。第二行......
  • Python 机器学习 K-近邻算法 KD树
    在使用K-近邻(KNN)算法时,kd树(k-dimensionaltree)是一种用于减少计算距离次数从而提高搜索效率的数据结构。kd树是一种特殊的二叉树,用于存储k维空间中的数据点,使得搜索最近邻点更加高效。KD树的构造过程是将数据分割成更小的区域,直到每个区域满足特定的终止条件。1、构建KD树在k......
  • 压缩算法_quicklz接口demo
    1quicklz  quicklz是单片机上一个常见的压缩算法,具体原理没有文档和hash表的相关基础我就不去深究了;  只需要将fileSrc.txt放在桌面,代码可以使用vscode的mingw直接编译;2quicklz源码quicklz.h/***quicklz.h*********************************************************......
  • 单源正权最短路径——Dijkstra算法
    目录问题引入思路一览算法原理code问题引入给出n点m边,其中边的权值皆为非负数,要求快速给出一个点到其余点的最短距离思路一览dfs遍历维护最短距离floyd算法算全源最短,但是这玩意时间复杂度O(n3),最多也就1000个点左右主角Dijkstra算法算法原理主要是以源点为根节点逐步构......