zoukankan      html  css  js  c++  java
  • 浅谈树状数组(为什么lowbit(x)=x&(-x)

    树状数组是一种支持单点修改和查询前缀和的数据结构 网上很多讲解它的博客了 这里重点讲一下为什么lowbit(x)=x&(-x)

    树状数组代码量相对于线段树基本可以不计(太好写了) 因此NOIp基本不考(?)

    但是作为最好写的树状结构 值得好好理解

    关于为什么LOWBIT( X ) = X &( -X )

    lowbit 要的是你从末尾开始第1个 1 所代表的值

    example:13=1101(8+4+1)所以LOWBIT(13)= 1;

    那么暴力写一个lowbit就是

    #include<bits/stdc++.h>
    using namespace std;
    long long lowbit(long long x){
    	int ans=1;
    	while (1){
    		if( x & 1 ) return ans;
    		else {
    			x=x>>1;
    			ans=ans<<1; 
    		}
    	}
    }
    int main()
    {
    	long long n;
    	cin>>n;
    	cout<<lowbit (n);
    	return 0;
    }
    

      如果有什么运算符不懂就去百度吧~~~讲的很清楚

    但是实际上我们有更好的做法。

    要理解为甚LOWBIT(X)=X&-X 要先去百度 反码 和 补码 (超链接都帮你做好了不点一下吗)

    欢迎回来 现在我们来聊原理

    x变成负数时 他末尾的0全变成1 然后加1又全都变成0

    还是举个例子13=1101 反码变成0010 加1变成0011

    按位与一下 只有末尾和他都是1 于是lowbit(13)=1

    16=10000 反码变成01111 加1变成10000 

    按位与时变成10000即16

    负数完美的帮你进行了一个反位加1的操作

    帮你把原来末尾上一连串的零变成1

    再变成0

    在最后一堆零的前一位留了一个1 而你要做的就是找见那个1在哪 

    如果这个位原来是1 反位加1让他不变 那么肯定这个位原来以前全是0000 

    所以就出来了 非常巧妙

    每一个数组的区间范围为【x-lowbit[x]】~【x】

    剩下的翻翻其他人博客就对上啦 祝你好运

    TAG:SIN_XIII ⑨

  • 相关阅读:
    什么是仿射变换
    转:vim比较好的学习资料
    学好C++的五十条建议
    转:美国设置地理系的大学名单
    转:windows下安装emacs
    我学习GNU/Linux: 如何上手
    Linux学习路线图 (转载)
    unix编程学习路线图(转)
    转:C++资源之不完全导引
    Why Linux Programming?
  • 原文地址:https://www.cnblogs.com/SINXIII/p/10388920.html
Copyright © 2011-2022 走看看