首页 > 其他分享 >树状数组

树状数组

时间:2022-10-08 22:24:01浏览次数:45  
标签:结点 树状 int lowbit 数组 logn

引入问题

给出一个长度为n的数组,完成以下两种操作:

  1. 将第i个数加上k
  2. 输出区间[i,j][i,j]内每个数的和

朴素算法
单点修改:O(1)O(1)
区间查询:O(n)O(n)
使用树状数组
单点修改:O(logn)O(logn)
区间查询:O(logn)O(logn)**


前置知识

lowbit()lowbit()运算:非负整数xx在二进制表示下最低位1及其后面的0构成的数值。


举例说明:
lowbit(12)=lowbit([1100]2)=[100]2=4lowbit(12)=lowbit([1100]2)=[100]2=4
函数实现:

int lowbit(int x)
{
    return x & -x;
}

树状数组思想

树状数组的本质思想是使用树结构维护”前缀和”,从而把时间复杂度降为O(logn)O(logn)。

对于一个序列,对其建立如下树形结构:


每个结点t[x]保存以x为根的子树中叶结点值的和
每个结点覆盖的长度为lowbit(x)
t[x]结点的父结点为t[x + lowbit(x)]
树的深度为log2n+1log2n+1


树状数组操作

add(x, k)表示将序列中第x个数加上k。

以add(3, 5)为例:
在整棵树上维护这个值,需要一层一层向上找到父结点,并将这些结点上的t[x]值都加上k,这样保证计算区间和时的结果正确。时间复杂度为O(logn)O(logn)。

void add(int x, int k)
{
    for(int i = x; i <= n; i += lowbit(i))
        t[i] += k;
}

ask(x)表示将查询序列前x个数的和

以ask(7)为例:
查询这个点的前缀和,需要从这个点向左上找到上一个结点,将加上其结点的值。向左上找到上一个结点,只需要将下标 x -= lowbit(x),例如 7 - lowbit(7) = 6。

int ask(int x)
{
    int sum = 0;
    for(int i = x; i; i -= lowbit(i))
        sum += t[i];
    return sum;
}

标签:结点,树状,int,lowbit,数组,logn
From: https://www.cnblogs.com/mrkou/p/16770486.html

相关文章

  • ajax 传递一个数组
    (一)java后端publicStringgetTextContent(@RequestParam(name="titleId")IntegertitleId,HttpSessionsession){//取答案//获取题目问题信息Midautumn2022Entity......
  • PHP 多维数组排序学习
    <?php$content_a['score']=3;$content_a['name']='3name';$content_b['score']=6;$content_b['name']='3name';$list1[]=$content_a;$list1[]=$content_b;print......
  • day11 -数组
    数组特点长度确定。一旦被创建大小不可以改变其元素必须是相同类型,不允许出现混合类型元素可以是任何数据类型,包括基本类型和引用类型数组变量属于引用类型,数......
  • 树状结构查找爹们
    我有原始数据如下constnodes={id:"abc",name:"爷爷",children:[{id:"def",name:"爹",children:[{id:"jkl",name:"我"}......
  • 数组:
    给定两个数组,arr1和 arr2,arr2 中的元素各不相同arr2中的每个元素都出现在 arr1 中对arr1 中的元素进行排序,使arr1中项的相对顺序和 arr2 中的相对顺序相同......
  • 有一个整形数组,a[3] = {7,2,5},要求使用指针实现数组成员由小到大的顺序排列,即结果为:a[
    #include<iostream>#include<string>#include<windows.h>usingnamespacestd;voidswap(int*a,int*b){inttmp=*a;*a=*b;*b=tmp;}in......
  • 数组-算法-排序
    定义数组publicstaticvoidmain(String[]args){  //我们的数组必须初始化,才能使用  //动态出初始化:接受由我们指定的长度,由系统赋初始值  int[]arr=......
  • C# 最基础知识介绍(四)——数组、字符串、结构体、枚举、类
    C#最基础知识介绍(四)——数组、字符串、结构体、枚举、类数组(Array)......
  • 字符数组和字符串
      注意事项:  关于第三点:  后面?的表示垃圾值或是无用值,反正不知道 关于第四点:  数组已经满了,没有空间放结束标志\0了(空间足够的时候系统会自动给你......
  • 【重识Java】你这 数组 挺能藏啊?
    本文主要介绍一些关于Java数组的易错易忘的知识点,并不系统完善,如有在意,还请见谅。一、数组初始化......