• 树状数组&线段树


    先是树状数组

    令这棵树的结点编号为C1,C2...Cn。令每个结点的值为这棵树的值的总和,那么容易发现:
    C1 = A1
    C2 = A1 + A2
    C3 = A3
    C4 = A1 + A2 + A3 + A4
    C5 = A5
    C6 = A5 + A6
    C7 = A7
    C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
    ...
    C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16
    这里有一个有趣的性质:
    设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax,
    所以很明显:Cn = A(n – 2^k + 1) + ... + An
    算这个2^k有一个快捷的办法,定义一个函数如下即可:
    int lowbit(int x){
    return x&(x^(x–1));
    }
    利用机器补码特性,也可以写成:
    int lowbit(int x){
    return x&(-x);
    }
    以上来自百度百科。
    函数x=x&(-x)是求x节点所管理的点个数;
    衍生出两个函数:
    ①  x+=x&(-x)     ——x的父节点
    ②  x-=x&(-x)      ——x的下一个兄弟节点
       
     
    修改函数:
    因为修改一个函数,那么所有管辖他的点都要改变。
    void updata(int x, int num)      //x为你要修改的数组的点,num为你要加上的数。
    {
           while(x<=n)
          {
                d[x]+=num;
                x+=lowbit(x);   //求父节点的编号
           }
     
     
    求和函数,求1~x的和
    int  getsum(int x)
    {
          int   s=0;
          while(x>0)
           {
                s+=d[x];
                x-=x&(-x);    //下一个兄弟节点的编号
            }
            return s;
    }
  • 相关阅读:
    HTTP学习笔记(1)ULR语法
    wsdl地址如何在远程服务器上查看源码?
    java线程详解(三)
    java线程详解(二)
    java线程详解(一)
    java中this用法总结
    Linux运行python程序
    如何获取到Java对象的地址
    IDEA 远程调试
    linux环境中mysql默认端口3306无法连接问题排查
  • 原文地址:https://www.cnblogs.com/riddle/p/3248989.html
Copyright © 2020-2023  润新知