首页 > 其他分享 >树状数组(Binary Indexed Tree, BIT)

树状数组(Binary Indexed Tree, BIT)

时间:2024-09-26 09:34:47浏览次数:1  
标签:Binary 树状 int lowbit Tree 二进制 按位 数组 Indexed

树状数组(Binary Indexed Tree, BIT)

树状数组(Binary Indexed Tree, BIT),也称为 Fenwick Tree,是一种用于高效处理数组前缀和查询和单点更新的数据结构。它能够在 (O(\log n)) 时间内完成单点更新和前缀和查询操作。

基本概念

  1. 前缀和:给定一个数组 a,前缀和 prefix_sum[i] 表示 a[0] + a[1] + ... + a[i]
  2. 单点更新:更新数组 a 中的某个元素 a[i]

树状数组的结构

树状数组通过一种特殊的方式组织数组元素,使得前缀和查询和单点更新都能高效进行。具体来说,树状数组 bit 是一个与原数组 a 大小相同的数组,但它的每个元素 bit[i] 存储的是原数组 a 中某些元素的和。

树状数组的构建

  1. 更新操作

    • 更新 a[i] 时,需要更新 bit 中所有包含 a[i] 的元素。
    • 具体操作是:从 i 开始,不断将 i 加上其最低位的 1,直到超出数组范围。
  2. 查询操作

    • 查询 a[0] + a[1] + ... + a[i] 时,需要累加 bit 中某些元素的值。
    • 具体操作是:从 i 开始,不断将 i 减去其最低位的 1,直到 i 变为 0。

lowbit 原理

lowbit 是一个在树状数组(Binary Indexed Tree, BIT)中常用的操作,用于获取一个整数的二进制表示中最低位的 1 及其后面的 0 所构成的数值。具体来说,lowbit(x) 返回的是 x 的二进制表示中最低位的 1 及其后面的 0 所构成的数值。

原理

lowbit 的原理基于补码表示法。对于一个正整数 x,其 lowbit 可以通过以下公式计算:

[ \text{lowbit}(x) = x & (-x) ]

这里的 & 表示按位与操作。

解释

  1. 补码表示

    • 在计算机中,负数通常以补码形式存储。对于一个正整数 x,其负数 -x 的补码表示是 x 的二进制表示按位取反后加 1。
  2. 按位与操作

    • 按位与操作 & 会将两个数的二进制表示中对应位都为 1 的位保留,其他位变为 0。
  3. 计算 lowbit

    • 对于一个正整数 x,其补码表示 -x 的二进制形式中,最低位的 1 及其后面的 0 会与 x 的二进制形式中相同位置的 1 对应。
    • 因此,x & (-x) 的结果就是 x 的二进制表示中最低位的 1 及其后面的 0 所构成的数值。

示例

假设 x = 6,其二进制表示为 0110

  1. x 的补码表示 -x-6,其二进制表示为 1010(按位取反后加 1)。
  2. 进行按位与操作:
    • 0110 (6)
    • 1010 (-6)
    • 0010 (2)

因此,lowbit(6) 的结果是 2

以下是一个简单的 lowbit 函数实现:

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

代码实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+100,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
int n,m;
int a[N];
int c[N];
int lowbit(int x)
{
    return x&(-x);
}
int query(int x)
{
    int s=0;
    for(;x>0;x-=lowbit(x))
    {
        s+=c[x];
    }
    return s;
}
void modify(int id,int x)
{
    for(;id<=n;id+=lowbit(id))
    {
        c[id]+=x;
    }
}
void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i],modify(i,a[i]);
    while(m--)
    {
        int id,x,y;
        cin>>id>>x>>y;
        if(id==1) modify(x,y);
        else cout<<query(y)-query(x-1)<<endl;
    }
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;
    while(T--)
     {
         solve();
     }
     return 0;
} 

标签:Binary,树状,int,lowbit,Tree,二进制,按位,数组,Indexed
From: https://www.cnblogs.com/Violetfan/p/18432793

相关文章

  • PAT甲级-1115 Counting Nodes in a Binary Search Tree
    题目 题目大意给定节点个数,以及每个节点的值,要求构造一棵二叉排序(搜索)树,并按照规定格式输出最后一层和倒数第二层的节点个数。思路二叉排序树的构造方法是递归,但思路类似于二分查找。逐个将n个节点插入到二叉排序树中,插入完成也就构造完成了。插入节点时,如果该节点值大于......
  • 大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(正在更新···)章节内容上节我们完成了如下的内容:表引擎详解介绍日志......
  • 大数据-139 - ClickHouse 集群 表引擎详解4 - MergeTree 实测案例 ReplacingMergeTree
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(正在更新···)章节内容上节我们完成了如下的内容:MergeTree存储结构Me......
  • [ARC121E] Directed Tree 题解
    简单容斥题。思路题面的条件相当于一个位置上填的点不能是自己的祖先。发现直接做并不好做。考虑容斥。我们想要求出\(f_i\)为至少有\(i\)个不合法位置的方案数。那么答案为:\[\sum_{i=0}^nf_i(-1)^i\]如何求解。设\(f_{i,j}\)为\(i\)子树下有\(j\)个不合法位......
  • CF1446C Xor Tree
    很有意思的题目,我们考虑能连边的两个数一定是在01-Trie上距离最近的两个点。于是我们先把所有数插入到01-Trie上去,然后\(dp_u\)考虑以\(u\)为根的子树中最多能留几个数,他的两个儿子内部的点只能在内部转移,你只能取一个儿子和另一个儿子的一个,也就是说我们的转移为\(dp_u......
  • windows rb_tree动画
    #defineUNICODE#include<windows.h>#include<windowsx.h>#include<stdbool.h>#include<stdio.h>typedefstructball_tball_t;structball_t{intsrc_x;intsrc_y;inttarget_x;inttarget_y;};constintWI......
  • 大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(正在更新···)章节内容上节我们完成了如下的内容:MergeTree实测案例Re......
  • 大数据-138 - ClickHouse 集群 表引擎详解3 - MergeTree 存储结构 数据标记 分区 索引
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(正在更新···)章节内容上节我们完成了如下的内容:MergeTree存储结构Me......
  • AT_jsc2021_g Spanning Tree 题解
    感觉自己稍微有一点唐了。思路我们首先可以把一定要连的边连起来。这样就变成了一个无向图生成树计数问题。如何求解。使用矩阵树定理!我们可以求出基尔霍夫矩阵,然后跑一遍行列式就可以了。时间复杂度:\(O(n^3)\)。Code#include<bits/stdc++.h>usingnamespacestd;con......
  • 万象更新 Html5 - h5: h5 IndexedDB: 保存二进制数据
    源码https://github.com/webabcd/Html5作者webabcd万象更新Html5-h5:h5IndexedDB:保存二进制数据示例如下:h5\indexedDB\demo3.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>IndexedD......