[数据结构] 树状数组 的C程序实现

int tree[100001];//树状数组,用于取区间[x,y]的数据的和

/*
 & 特殊运算,t&(-t)的值(十进制),就是t在2进制下,从右往左数第一个1出现的位置。
 结合树状数组的特殊性质,这个值有用
 */
int lowbit(int t)
{
    return t&(-t);
}
/*
 假设对处在数组序号x的数据进行了更改,让x位置的数据有了增量v
 对树状数组进行如下修改,使相关的包含x位数据的和都增加v
 根据树状数组的性质,也就是对下标为 x, x+lowbit(x), x+lowbit(x+lowbit(x))....的数据都加v
 */
void add(int x,int v)
{
    for(int i=x; i<=100000; i+=lowbit(i)) tree[i]+=v;
}
/*
 取区间[0,x]的数据的和
*/
int getsum(int x)
{
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i))
        ans+=tree[i];
    return ans;
}
/*
 二分查找,进一步减少时间复杂度
 */
int binarySearch(int l, int r, int median)
{
    int mid ;
    while (l<=r)
    {
        mid = (l+r)/2;
        if (getsum(mid)<median)  l = mid+1;
        //注意此处是 >=
        else if (getsum(mid)>=median) r = mid-1;
        else return mid;
    }
    return l;
}

原文地址:https://www.cnblogs.com/OranBlog/p/9012351.html

时间: 2024-07-31 06:37:22

[数据结构] 树状数组 的C程序实现的相关文章

数据结构——树状数组

我们今天来讲一个应用比较广泛的数据结构——树状数组 它可以在O(nlogn)的复杂度下进行单点修改区间查询,下面我会分成三个模块对树状数组进行详细的解说,分别是树状数组基本操作.树状数组区间修改单点查询的实现.树状数组查询最值的实现 一. 树状数组一般分为三种操作,初始化.修改.查询 在讲基本操作之前,我们先来看一张图 这张图就是树状数组的存储方式,对于没有接触过树状数组的人来说看懂上面这张图可能有些困难,上图的A数组就是我们的原数组,C数组则是我们需要维护的数组,这样存储能干什么呢,比如我们在

HDU 1556 数据结构-树状数组-改段求点

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556 解题思路:树状数组,只要了解树状数组的原理就不用死记模板了,总之树状数组管理的就是前缀和,高度越高的的结点管理的范围越广 所以要是改点求段:更改一个点就要向上传递 所以要是改段求点:更改一个点就要向下传递 代码: #include <cstdio> #include <iostream> #include <cstring> using namespace std;

数据结构——树状数组篇

原地址:My CSDN Blog  那边还未通过审核,先看这边的吧…… 线段树是一个很好的维护区间关系的这样的一个数据结构,但是,很多时候我们可以用更小空间.更快速度(更大尺寸呢.,全景天窗,五菱宏光?)的数据结构来维护一个前缀关系. ??? 上面的这张图是表示的一个有8个叶子节点的线段树,接下去,我们给它进行一个变形: ??? 然后呢,我们把2.4.6.8.……这样的元素推到最顶端的空上边去,想让2表示1-2这段区间,让4表示1-4这段区间,让6表示5-6这段区间,让8表示1-8这段区间. 然

实用数据结构---树状数组(二叉索引树)

树状数组适用于动态连续和查询问题,就是给定一个区间, 查询某一段的和或者修改某一位置的值. 关于树状数组的结构请去百度百科,否则将看不懂下面内容 我们看这个题 士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧. 南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新

用树状数组处理逆序对[数据结构][树状数组]

逆序对 ——!x^n+y^n=z^n 可以到这里[luogu]: https://www.luogu.org/problem/show?pid=1908 题意:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对.知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目. 假如为这些数为: 8 2 3 1 7 如果我们把数一个个加进来,用一个数组a[i]统计i出现了几次. a的初始状态: 8加进来后: 由于不存在比8大的数,说明没有产生逆序对 2加进来后: 统计比2大

ACM数据结构-树状数组

模板: int n; int tree[LEN]; int lowbit(int x){ return x&-x; } void update(int i,int d){//index,delta while(i<=n){ tree[i]+=d; i+=lowbit(i); } } int getsum(int i){ int ans=0; while(i>0){ ans+=tree[i]; i-=lowbit(i); } return ans; } 示意图: 1.Ultra-Quic

2019.9.25 初级数据结构——树状数组

一.树状数组基础 学OI的同学都知道,位运算(对二进制的运算)比普通运算快很多.同时我们接触到了状态压缩的思想(即将0-1的很多个状态压缩成十进制的一个数,每一个二进制位表示一个状态).由于在实际做题过程当中,由于数据范围限制,我们必须采用更高效的存储.查询方法,于是树状数组应运而生. 首先我们检查传统的存储状态.对于数组的每一个下标i,其所存储的有效信息只有一个a[i](这是传统数组).而对于树状数组,我们每一位下标可以存储lowbit(i)个有效信息.这个lowbit运算一会再说.所以尽管树

C++-hdu1166-敌兵布阵[数据结构][树状数组]

单点修改+区间查询=树状数组 空间复杂度O(n) 时间复杂度O(mlogn) 1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <queue> 5 #include <vector> 6 #include <cstdio> 7 #include <cstdlib> 8 #include <cstring> 9 #include <

C++-hdu1394-Minimum Inversion Number[数据结构][树状数组]

给出0~n-1的一个排列,可以整体移动,求逆序对最小值 把数字num[i]的加入,等价于树状数组的第n-num[i]位加1 因为num[i]是第 (n-1)-num[i]+1=n-num[i]大的数字,产生逆序对,只可能在其之前已经插入了数字,此时直接区间查询即可 1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <queue> 5 #include <vector>