ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

数据结构和算法 - 树状数组

2022-04-04 23:04:14  阅读:165  来源: 互联网

标签:树状 int lowbit 复杂度 算法 数组 区间 操作 数据结构


树状数组

1. 问题

序号 题目
—— ——————————————————————————————————————————————————————
307. 区域和检索 - 数组可修改
493. 翻转对
HDU P1166 敌兵布阵

给定一个数组\(A\),长度为\(n\),数组的下标范围是\([0,n-1]\),对数组A可进行:

  1. 查询\([i,j]\)区间内的和;
  2. 对位置\(i\)的值,加一个值\(x\);

常规解决思路:抽象为“区间和查询”和“区间更新”问题,

  1. 模拟,操作1的时间复杂度是\(O(n)\),操作2的时间复杂度是\(O(1)\);
  2. 前缀和,操作1的时间复杂度是\(O(1)\),操作2的时间复杂度是\(O(n)\);

2. 定义

为了平衡操作1和操作2,引进了树状数组\(C\),即每个位置i表示原始数组的一个区间,值\(C[i]\)表示的是原始数组\(A\)中\([i-lowbit(i)+1, i]\)区间之和,其中\(lowbit(i)\) 表示数字i的二进制表示中,位数最低的1所代表的值,如:

\[\begin{array}{l} 1 -> [0] \\ 2 -> [1,2] \\ 3 -> [3] \\ 4 -> [1,2,3,4] \\ i -> [i-lowbit(i)+1, i] \\ \end{array} \]

个人理解:最低位的1的位置表示区间的长度,如\((1000)_{2}\)表示\([1,8]\)的区间。

3. 操作

  1. 二进制位
  2. 区间添加
  3. 区间查询
class TreeArray{
    
    vector<int> tr;
    vector<int> nums;
    int n;
    
    int lowBit(int x){
        return x & -x;
    }
    void add(int x, int u){
        for(int i=x; i<=n; i+=lowBit(i)){
            tr[i] += u;
        }    
    }
    int query(int x){
        int ans = 0;
        for(int i=x; i> 0; i -= lowBit(i)){
            ans += tr[i];
        }
        return ans;
    }
    
    // 初始化
    // for(int i=0; i< n;i++){
    //    add(i+1, nums[i]);
    //}
    
    // 区间和
    // sumRange: query(right+1) - query(left);
};

4. 复杂度

时间复杂度:\(O(\log(n))\)

空间复杂度:\(O(n)\)

标签:树状,int,lowbit,复杂度,算法,数组,区间,操作,数据结构
来源: https://www.cnblogs.com/yangliuly1/p/16100903.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有