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

树状数组

时间:2023-12-12 12:33:07浏览次数:26  
标签:树状 int 复杂度 数组 logn sum

树状数组所维护的数组记为\(a\),\(n\)表示\(a\)中元素个数,\(lowbit(i)\)表示最低位\(1\)和后面所有\(0\)组成的数,\(c[i]\)表示\(a\)区间\([i - lowbit(i) + 1, i]\)的和。

\(add(k, x)\):单点修改,表示\(a[k]=a[k]+x\),时间复杂度:\(O(logn)\)。

\(sum\):区间查询,\(sum(k)\)表示\(a\)区间\([1, k]\)的和,\(sum(l, r)\)表示区间\([l,r]\)的和,时间复杂度:\(O(logn)\)。

\(kth(k)\):求第\(k\)小的数,\(a\)应为权值数组,即\(a[i]\)表示数\(i\)出现的次数,此时树状数组为权值树状数组,时间复杂度:\(O(logn)\)。

template <typename T>
class Fenwick 
{
private:
    int n;
    std::vector<T> c;
    #define lowbit(x) (x & -x)
public:
    Fenwick(int n) : n(n - 1), c(n) {}
    
    void add(int k, T x)
    {
        for (int i = k; i <= n; i += lowbit(i)) c[i] += x;
    }
    
    T sum(int k)
    {
        T sum = T();
        for (int i = k; i; i -= lowbit(i)) sum += c[i];
        return sum;
    }
    
    T sum(int l, int r) 
    {
        return sum(r) - sum(l - 1);
    }

    int kth(T k)
    {
        int x = 0;
        for (int i = 1 << __lg(n); i; i >>= 1) 
            if (x + i <= n && k > c[x + i]) 
                x += i, k -= c[x];    
        return x + 1;
    }
};

标签:树状,int,复杂度,数组,logn,sum
From: https://www.cnblogs.com/xiojoy/p/17896517.html

相关文章

  • Java数组
    免责声明:java基础资料均来自于韩顺平老师的《循序渐进学Java零基础》教案,具体视频内容可以去B站观看,这些资料仅用于学习交流,不得转载用于商业活动1.数组数组可用存放多个同一类型的数据,数组也是一种数据类型,是引用类型1.1一维数组1.1.1使用方式1-动态初始化语法:数据类型数......
  • linux 中 数组的常见操作
     001、创建数组(三种方法)(下标连续数组和下标不连续数组)a、 002、访问数组(访问全部元素;访问单个元素) 003、遍历数组(利用循环实现;for;while) 004、输出数组的长度(下标连续和下标不连续) 005、输出数组的下标(下标连续和下标不连续) 006、输出数组中每个元素的长度 00......
  • 88. 合并两个有序数组
    1.题目介绍给你两个按非递减顺序排列的整数数组 \(nums1\)和\(nums2\),另有两个整数\(m\)和\(n\),分别表示\(nums1\)和\(nums2\)中的元素数目。请你合并\(nums2\)到\(nums1\)中,使合并后的数组同样按非递减顺序排列。注意:最终,合并后数组不应由函数返回,而是存......
  • java 数组添加元素的两种方法
    方式一:创建一个新数组,长度为原数组加1,然后将原数组数据添加到新数组,最后再添加需要的新数据 @Testpublicvoidredd111(){String[]s1={"aaa","bbb","ccc"};String[]s2=newString[s1.length+1];for(inti=0;i<s1.length;i++){......
  • JAVA 给数组添加元素
    组是不可变长度,那么已经定义的数组,怎么添加元素呢?//1.已有的数组column和list集合String[]column={"身份证号","员工编号","姓名"};List<String>list=newArrayList<>();list.add("奖金");list.add("提成&q......
  • 写class的奇淫巧技-数组遍历
    class想提供类似数组的能力可以自定义Symbol.iteratorclassA{ *[Symbol.iterator](){ yieldthis.x; yieldthis.y; yieldthis.z; }}如:......
  • 列表 切片 动态数组
    切片(slice)是一种动态数组的抽象。切片提供了对数组的一段连续片段的引用,并且可以动态增长或缩小。与数组不同,切片的长度是可变的,可以根据需要进行调整,而且切片是引用类型 创建空切片varnumbers[]int创建切片2slice1:=[]int{1,2,3,4,5}packagemai......
  • 【算法】【线性表】两个排序数组的中位数
    1 题目两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log(m+n))。中位数的定义:这里的中位数等同于数学定义里的中位数。中位数是排序后数组的中间值。如果有数组中有n个数且n是奇数,则中位数为 A((n-1)/2)。如果有数组中有n个数且n......
  • 逆序对——权值树状数组+离散化
    给定一个长度为n的整数数列,请你计算数列中的逆序对的数量。每个数字不超过1e9。intn,m;inta[N];inttr[N];vector<int>lan;intlowbit(intx){ returnx&(-x);}voiddiscrete(){sort(lan.begin(),lan.end());//排序lan.erase(unique(lan.begin(),l......
  • Python NumPy 合并数组和分割数组
    在Python的NumPy库中,合并和分割数组是两种常用的操作,用于重组和分解数据集。将多个数据集合并为一个数据集,方便进行后续的处理。将数据集拆分为多个子数据集,用于并行处理或分布式处理。将数据集按指定条件进行分组,方便进行分析。1、合并数组合并数组是一种常见操作,允许你......