zoukankan      html  css  js  c++  java
  • 树状数组&线段树

    先是树状数组

    令这棵树的结点编号为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;
    }
  • 相关阅读:
    .Net Cache及(HttpRuntime.Cache与HttpContext.Current.Cache的区别)
    Autofac 属性注入的方式
    AutoFac创建实例的方法解析
    MongoDB 增删改查 CRUD 操作
    MongoDB 3.4版本在windows环境下的安装与配置
    Stack Overflow 2017 开发者调查报告
    使用SVN对GitHub进行版本管理
    MongoDB.Driver for C#
    Dapper.Net 轻量级的ORM 框架2
    Selenium webdriver 安装(一)
  • 原文地址:https://www.cnblogs.com/riddle/p/3248989.html
Copyright © 2011-2022 走看看