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

树状数组

时间:2023-04-02 23:44:38浏览次数:39  
标签:树状 int lowbit 元素 tree 更新 数组

当使用前缀和或者差分数组的时候,一般会遇到O(n2)的时间复杂度,此时我们可以使用树状数组来对时间复杂度进行优化。

树状数组主要是利用树形结构来优化我们前缀和或差分数组的计算复杂度使得O(n)的时间复杂度变为O(logn),使用总的时间复杂度减少到O(nlogn).。

构建树状数组的核心是lowbit:

lowbit(x)即x&(-x),效果为得到x最后一个1的位置。比如3&-3等于1表示3的最后一个1在第1位。

-3表示3的补码也就是取反加一。

总的代码如下:

#include <iostream>
using namespace std;
const int N = 1000;
#define lowbit(x) ((x)&-(x))
int tree[N] = { 0 };
void Update(int x, int d) {
    while (x <= N) {
        tree[x] += d;
        x += lowbit(x);
    }
}
int sum(int x) {
    int ans = 0;
    while (x > 0) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}
void Print_arr(int* arr,int size) {
    for (int i = 0; i < size; i++) {
        cout << *(arr + i) << " ";
    }
    cout << endl;
}
void Print_sum_arr(int size) {
    for (int i = 0; i <= size; i++) {
        cout << sum(i) << " ";
    }
}
int a[11] = { 0,4,5,6,7,8,9,10,11,12,13 };
int main()
{

    for (int i = 1; i <= 10; i++) Update(i, a[i]);
    //Print_arr(tree, 11);
    Print_sum_arr(11);
    cout << sum(8) - sum(4) << endl;
    return 0;
}

 

 (来自<<算法竞赛>>)

对于Update函数的说明:

void Update(int x, int d) {//更新所有在树状数组中与x有关的数据,使用lowbit查找
    while (x <= N) {
        tree[x] += d;
        x += lowbit(x);
    }
}

举例说明:对第一个元素更新的时候,1的lowbit为1,那么下一个更新的元素为2,2的lowbit为2,下一个更新4,4的lowbit为8更新8以此类推。

Update之和的,tree里面保存的元素对应上图中的a

 

对于sum函数的说明:

int sum(int x) {//求前缀和
    int ans = 0;
    while (x > 0) {
        ans += tree[x];
        x -= lowbit(x);//由于之前是按照+lowbit(x)进行更新的,现在-lowbit(x)得到的位置就是该位置前缀和需要用到的元素。
    }
    return ans;
}

举例说明:对于第8个元素,8的lowbit为8,但由于之前更新1,2,3,4,5,6,7的时候会对8更新,所以tree[8]就是前八个元素之和

举例说明2:对于第7个元素,7的lowbit为1,更新后6的lowbit为2,4的lowbit为3,结束更新。因此前七个元素之和计算公式为tree[7]+tree[6]+tree[4]。

    依次分析:tree[4]表示的是:1,2,3更新过以及4本身,因此tree[4]就是前四个元素之和。

          tree[6]表示的是5更新加上6本身,因此tree[6]是第5、6个之和

举例说明3:对于第6个元素,6的lowbit为2,那么-lowbit之和变为4,在进行-lowbit为0.因此前6个元素之和为tree[6]+tree[4]

    cout << "tree[4]:" << tree[4] << endl;
    cout << "tree[6]:" << tree[6] << endl;
    cout << "sum(6):" << sum(6) << endl;

 

 可以看到sum(6)为tree[4]和tree[6]之和

           

标签:树状,int,lowbit,元素,tree,更新,数组
From: https://www.cnblogs.com/hailanben/p/17281816.html

相关文章

  • C语言逆向——数组和结构体,数组多维只是一个编译构造的假象,本质会转成一维数组,结构体
    数组数组是C语言中非常重要的一个概念,学习C语言主要就是两个知识点:数组、指针,学好这两个,那么你的C语言一定也会很好。什么是数组?或者说什么情况下我们需要使用数组,比如说我们需要定义一个人的年龄,我们可以定义一个变量来表示,但是如果我们需要定义三个人的年龄呢?那就需要三个变......
  • 字符串和字符数组的区别
    intmain(){charstr1[]={'h','e','l','l','o'};charstr2="hello";//'\0'intlen1=sizeof(str1)/sizeof(char);//5intlen2=sizeof(str2)/sizeof(char);......
  • Shell 数组
    Shell数组数组中可以存放多个值。BashShell只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。与大部分编程语言类似,数组元素的下标由0开始。Shell数组用括号来表示,元素用"空格"符号分割开,语法格式如下:array_name=(value1value2...valuen)实例root@jdit:......
  • 12、数组
    1.数组的概念Go语言提供了数组类型的数据结构。数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串或者自定义类型。数组元素可以通过索引(位置)来读取(或者修改),索引从0开始第一个元素索引为0,第二个索引为1,以此类推。......
  • NOI 1.8编程基础之多维数组
    02:同行列对角线的格子1.描述输入三个自然数N,i,j (1<=i<=N,1<=j<=N),输出在一个N*N格的棋盘中(行列均从1开始编号),与格子(i,j)同行、同列、同一对角线的所有格子的位置。如:n=4,i=2,j=3表示了棋盘中的第二行第三列的格子,如下图:第一列第二列第三列第四列     ......
  • 数组练习1
    1、将密码文件的每一行作为元数赋值给数组  2、使用关联数组统计密码文件中用户使用的不同类型shell的数量   3、使用关联数组按扩展名统计指定目录中文件的数量  ......
  • 5.函数6.数组7.操作符8.常见关键字9.#define定义的常量和宏
    在我们学习的数学里面,函数的概念例子比如f(x)=2*x+1;  f(x,y)=x+y;在c语言也是同样的样子比如,我举例一条要相加的例子#definr_#include<stdio.h>intAdd(intx,inty)//int是他的返回类型是个整形,所以要加int//这就是一个函数add是自己创建的一个函数名,括号里面叫做函数的......
  • java数组的创建和使用
    声明数组必须先声明后使用,数组的声明有两种方法:1.C语言风格声明:dataTypearrayRefVar[];2.Java风格声明:dataType[]arrayRefVar;一般推荐使用第二种Java风格的声明方式。创建数组声明的数组并不具备物理空间,需要使用new操作符来创建数组,为其分配内存空间:dataType[......
  • Shell数组练习
    1、将/etc/shadow文件的每一行作为元素赋值给数组#!/bin/bash#统计行数,作为循环次数num=`wc-l</etc/shadow`for((i=0;i<=num;i++))do#根据i的变化取前i行内容再然后截取最后一行加入数组中array[$i]=$(head-$i/etc/shadow|tail-1)done#依次输出数组中......
  • 215. 数组中的第K个最大元素
    参考:https://leetcode.cn/problems/kth-largest-element-in-an-array/solutions/19607/partitionfen-er-zhi-zhi-you-xian-dui-lie-java-dai-/https://www.bilibili.com/video/BV1La411J7q9/?spm_id_from=333.999.0.0classSolution{publicintfindKthLargest(int[]n......