C语言树状数组的实例详解

首先需要了解什么是树状数组。树状数组(Binary Indexed Tree,BIT),也叫做 Fenwick 树(树状数组的发明者是Peter M. Fenwick),是一个查询和修改复杂度都为 log(n) 的数据结构,与线段树类似,但使用起来比线段树更加方便以及简洁。

在该攻略中,我们将通过两条树状数组的实例,详细讲解树状数组,让读者更好地理解树状数组的基本原理和应用。

示例一:树状数组求和

首先我们介绍一下树状数组的基本结构:

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

int c[maxn]; // 树状数组

其中lowbit是一个辅助函数,用来计算一个数的二进制表示下最低位的1所对应的数。即lowbit(x) = x & -x

c数组用于存储树状数组。

接下来,我们来看一个求和的例子。假设我们有一个长度为n的数组a

int a[maxn], c[maxn];
int n;

我们希望支持对a数组的区间求和,增加单个元素,查询单个元素等操作。我们可以使用树状数组来实现这些操作。具体的实现如下:

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

int c[maxn]; // 树状数组

void update(int x, int v) {
    while(x <= n){
        c[x] += v;
        x += lowbit(x);
    }
}

int query(int x) {
    int ans = 0;
    while(x){
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}

其中,update函数用来增加某个位置上的值,query函数用来查询一个区间的和。例如,要修改第i个位置上的元素,需要调用update(i, v)方法。而要求1~j的区间和,则需要调用query(j) - query(i - 1)方法。

例如,对于一个数组a = {1,2,3,4,5},我们可以先初始化树状数组:

for(int i = 1; i <= n; i++){
    update(i, a[i]);
}

接下来,我们可以调用query函数得到区间和:

int sum = query(j) - query(i - 1)

示例二:树状数组求逆序对

接下来,我们给出第二个例子:树状数组求逆序对。

逆序对的定义是,对于一个序列,如果 a[i] > a[j],且 i < j,则称 (i, j) 为一个逆序对。求解逆序对的个数是一个常见的问题。

我们可以使用树状数组来实现求逆序对的过程。具体实现如下:

const int maxn = 500010;
int a[maxn], c[maxn], n;

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

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

int sum (int x) {
    int ans = 0;
    for (int i = x; i > 0; i -= lowbit(i)){
        ans += c[i];
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    int ans = 0;
    for (int i = n; i > 0; i--){
        ans += sum(a[i] - 1);
        add(a[i], 1);
    }
    printf("%d\n", ans);
    return 0;
}

具体的实现如下:

  • 先从后往前遍历序列,每遍历到一个数,就把它放到树状数组中,并且统计一下在它之前小于它的数的个数,即sum(a[i] - 1)
  • 最终的答案即为累加得到的逆序对数。

例如,对于一个序列a = {3, 1, 2},我们可以先初始化树状数组:

for(int i = n; i > 0; i--){
    add(a[i], 1);
}

然后就可以累加逆序对数:

int ans = 0;
for (int i = n; i > 0; i--){
    ans += sum(a[i] - 1);
}
printf("%d\n", ans);

通过以上两个例子,我们可以看到树状数组在数据结构和算法中的广泛应用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言树状数组的实例详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Redis数据结构之链表与字典的使用

    Redis是一个开源、基于内存的数据结构存储系统。Redis支持多种数据类型,包括字符串、整数、浮点数、列表、哈希表、集合、有序集合等。本文将详细介绍Redis数据结构之链表与字典的使用。 链表 链表是Redis中常用的数据结构之一,主要用于存储有序的元素列表。链表中的每个元素都包含了一个指向前驱元素和后继元素的指针,这种结构可以方便地实现链表的插入、删除和…

    数据结构 2023年5月17日
    00
  • Java深入了解数据结构之栈与队列的详解

    Java深入了解数据结构之栈与队列的详解 1. 栈的概念 栈(Stack)是一种先进后出的数据结构,类似于一个箱子,新的物品只能放到箱子的顶部,旧的物品只能从箱子的顶部取出。栈通常有下面几个基本操作: push:将元素压入栈中,放在栈顶。 pop:将栈顶元素弹出,如果栈为空,则抛出异常。 peek:返回栈顶元素,但不将其弹出,如果栈为空,则抛出异常。 isE…

    数据结构 2023年5月17日
    00
  • Java数据结构之实现哈希表的分离链接法

    Java数据结构之实现哈希表的分离链接法 哈希表是一种非常常用的数据结构,它将数据存储在一个数组中,每个数组元素都存储着链表中的一个节点,这样可以实现高效的数据存储和查找操作。在哈希表中,我们可以通过哈希函数将关键字映射到数组中的特定位置。 但是,当哈希表的负载因子过高时,就会造成哈希冲突,这意味着两个或更多的关键字映射到了同一个数组位置。一种常见的解决方案…

    数据结构 2023年5月17日
    00
  • 带你了解Java数据结构和算法之2-3-4树

    带你了解Java数据结构和算法之2-3-4树 1. 什么是2-3-4树 2-3-4树是一种自平衡二叉查找树,也叫B树的一种,它可以保持树的平衡,使得每个节点的左右子树高度差最多为1。在2-3-4树中,每个节点可以包含2个、3个或4个子节点,这也是其名称的来源。2-3-4树是B树的特殊形式,通常用于内存储存结构。 2. 2-3-4树的特点 2-3-4树的特点如…

    数据结构 2023年5月17日
    00
  • 一文学会数据结构-堆

    一文学会数据结构-堆 什么是堆 在计算机科学中,堆是一个特殊的树状数据结构。堆通常有如下几个特性: 堆是完全二叉树; 堆中每个节点的值都大于或等于(小于或等于)其子节点的值,这个取值规则称为堆的“属性”; 堆顶元素(即根节点)总是为最大值或最小值。 堆的种类 堆分为小根堆和大根堆两种。小根堆要求每个节点的值都不大于其父节点的值,即A[PARENT[i]] &…

    数据结构 2023年5月17日
    00
  • C语言编程数据结构线性表之顺序表和链表原理分析

    C语言编程数据结构线性表之顺序表和链表原理分析 线性表的定义 线性表是由n(n>=0)个数据元素a1、a2、…、an组成的有限序列,通常用(a1, a2, …, an)表示,其中a1是线性表的第一个元素,an是线性表的最后一个元素。线性表中的元素个数n称为线性表的长度,当n=0时,线性表为空表。 线性表的分类 根据存储结构,线性表可以分为顺序表…

    数据结构 2023年5月17日
    00
  • Java 数据结构与算法系列精讲之哈希算法实现

    Java 数据结构与算法系列精讲之哈希算法实现 什么是哈希算法? 哈希算法是一种能将任意长度的消息压缩到某一固定长度的消息摘要的算法。 通过哈希算法,我们可以将一个任意的大数据量压缩成一段固定长度的数据,这个数据的长度通常比较小,相对于原数据的大小来说,要小得多。哈希算法的压缩特性使得它经常用来进行信息摘要、数据校验、唯一识别等功能,可以很大程度上提高数据的…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构之广义表的定义与表示方法详解

    JavaScript数据结构之广义表的定义与表示方法详解 什么是广义表 广义表是一种包含了无数元素的数据结构,可以是元素或者嵌套的子表。广义表可以表示为: $\quad\quad\quad GL = (a_0,a_1,…,a_n)$ 其中$a_i$可以是元素或者一个子表,如果$a_i$为一个子表,那么$a_i$本身也是一个广义表。广义表中,第一个元素$a…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部