【算法】树状数组和线段树

这篇具有很好参考价值的文章主要介绍了【算法】树状数组和线段树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、树状数组

O ( l o g n ) O(logn) O(logn) :单点修改、区间查询

与前缀和的区别:

  1. 前缀和是离线的,每次动态修改原数组某个元素,都需要重新求一遍前缀和,因此单点修改是 O ( n ) O(n) O(n) 的,区间查询则是 O ( 1 ) O(1) O(1)
  2. 树状数组是在线的,单点修改和区间查询都是 O ( l o g n ) O(logn) O(logn)

设下标从 1 1 1 开始

//树状数组的定义
t[x] = a[x - lowbit(x) + 1, x]

区间查询:求一段区间和

int query(int x)//[1, x]区间和
{
    int res = 0;
    for(int i = x; i > 0; i -= lowbit(i)) res += t[i];
    return res;
}

单点修改:给某个数加上一个数

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

lowbit

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

二、线段树

线段树是一种二叉树,可以 O ( l o g n ) O(logn) O(logn) 维护区间的某种属性比如:区间和、区间最值

//线段树的定义
struct node
{
	int l, r, v;  
}t[4 * N];

//设根结点为1
//结点u的左孩子是2 * u,右孩子是2 * u + 1

下面以维护区间和为例:

树状数组能做的,线段树都能做,比如单点修改、区间查询

后序遍历建树

int a[N];//原数组

void build(int u, int l, int r)
{
    t[u] = {l, r};

    if(l == r)
    {
        t[u].v = a[l];
        return;
    }
    
    int mid = (l + r) / 2;
    build(2 * u, l, mid);
    build(2 * u + 1, mid + 1, r);
    pushup(u);
}

区间查询:求一段区间和

int query(int u, int l, int r)
{
    if(t[u].l >= l && t[u].r <= r) return t[u].v;
    
    int mid = (t[u].l + t[u].r) / 2;
    int res = 0;
    if(l <= mid) res += query(2 * u, l, r);
    if(r > mid) res += query(2 * u + 1, l, r);
    return res;
}

单点修改:给某个数加上一个数

void modify(int u, int x, int v)//a[x] + v
{
    if(t[u].l == t[u].r)
    {
        t[u].v += v;
        return;
    }
    
    int mid = (t[u].l + t[u].r) / 2;
    if(x <= mid) modify(2 * u, x, v);
    else modify(2 * u + 1, x, v);
    pushup(u);
}

pushup文章来源地址https://www.toymoban.com/news/detail-826510.html

void pushup(int u)
{
    t[u].v = t[2 * u].v + t[2 * u + 1].v;
}

到了这里,关于【算法】树状数组和线段树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【高级数据结构】树状数组

    目录 树状数组1 (单点修改,区间查询) 树状数组2(区间修改,单点查询) 树状数组1 (单点修改,区间查询) 题目链接:洛谷 树状数组1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 将某一个数加上 x 求出某区间每一个数的和 输入格式 第一行包含两个正

    2024年02月15日
    浏览(46)
  • 【高级数据结构】线段树

    目录 树状数组1(单点修改,区间查询) 树状数组2(区间修改,单点查询) 线段树1(区间修改,区间查询) 代码源线段树1(查询最小值出现次数)  代码源线段树2(最大字段和) 树状数组1(单点修改,区间查询) 题目链接:  https://www.luogu.com.cn/problem/P3374 代码: 树状

    2024年02月15日
    浏览(38)
  • 数据结构与算法 | 数组(Array)

    数组(Array)应该是最基础的数据结构之一,它由相同类型的元素组成的集合,并按照一定的顺序存储在内存中。每个元素都有一个唯一的索引,可以用于访问该元素。 数组索引(Index): 数组中的每个元素都有一个唯一的整数索引,从0开始计数。索引用于访问数组中的元素

    2024年02月08日
    浏览(48)
  • 数据结构与算法(一): 稀疏数组

    在五子棋游戏或类似的游戏中,我们可以把整个棋盘想象成是一个有规律的二维数组,其值由0、1、2三个数字组成,0代表空白区域,1代表白子,2代表黑子。这种情况:即当一个数组中大部分元素为0或者为同一值时,存储该数组数据可以使用稀疏数组来对原始数组进行精简,

    2024年02月11日
    浏览(45)
  • JavaScript数据结构与算法整理------数组

            数组的标准定义: 一个存储元素的线性集合,元素可以通过索引来任意存取,索引通常是数字,用来计算元素之间存储位置的偏移量 ,几乎所有的编程语言都有类似的数据结构,而JavaScript的数组略有不同。         JavaScript中的数组是一种特殊的对象,用来表示偏

    2023年04月24日
    浏览(59)
  • 【数据结构和算法】寻找数组的中心下标

    Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 前缀和的解题模板 2.1.1 最长递增子序列长度 2.1.2 寻找数组中第 k 大的元素 2.1.3 最长公共子序列长度 2.1.4 寻找数组中第 k 小的元素 2

    2024年02月04日
    浏览(50)
  • 数据结构与算法-数组(附阿里面试题)

            给你一个文件里面包含全国人民(14亿)的年龄数据(0~180),现在要你统计每一个年龄   有多少人?          给定机器为 单台+2CPU+2G内存。不得使用现成的容器,比如map等。 (这一句可以忽略)         在以上情况下你该如何以最高效的方法来解决这个

    2024年02月13日
    浏览(34)
  • 【数据结构和算法】使用数组的结构实现链表(单向或双向)

    上文我们通过结构体的结构实现了队列 、以及循环队列的实现,我们或许在其他老师的教学中,只学到了用结构体的形式来实现链表、队列、栈等数据结构,本文我想告诉你的是,我们 可以使用数组的结构实现链表、单调栈、单调队列 目录 前言 一、用数组结构的好处 1.数

    2024年01月20日
    浏览(70)
  • 【数据结构与算法——TypeScript】数组、栈、队列、链表

    解决问题 的过程中,不仅仅 数据的存储方式会影响效率,算法的优劣也会影响效率 什么是算法? 定义: 🟢 一个有限指令集,每条指令的描述不依赖于言语 (编写指令:java/c++/ts/js) 🟢 接收一些输入(有些情况下不需要输入)(接收:排序:无序数组) 🟢 产生输出 (

    2024年02月14日
    浏览(36)
  • 数据结构与算法·第5章【数组和广义表】

    两种顺序映象的方式: 以行序为主序(低下标优先); 以列序为主序(高下标优先)。 而 n n n 维数组: LOC(x1, x2, ..., xn) = LOC(0, 0, ..., 0) + [(x1 × b1 + x2) × b2 + x3] × b3 + ... + xn 数据类型定义 其中: A.bounds是每一维可以放多少元素: a[A.bounds[0]][A.bounds[1]][A.bounds[2]]…… A.constants是指向每

    2024年02月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包