当前位置: 首页 > article >正文

线段树与树状数组 (C++)

线段树:基于分治思想的二叉树,用于维护区间信息(区间和,区间最值等),区间修改和区间查询的时间复杂度为logn

叶子节点存储元素本身,非叶子节点存取区间信息

1.节点:是一个结构体,包含l,r,sum

l,r为区间左右端点,sum为区间和

struct node{
    int l , r;
    int sum;
}st[N*4];

2.递归建树:

父节点编号为p,左孩子2*p,右孩子2*p+1

void build(int u, int l, int r)
{
    if (l == r) tr[u] = {l, r, w[r]};
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        tr[u].sum = tr[u<<1].sum + tr[u<<1|1].sum;
        //也可以用pushup(u); 因为有节点新增,所以要向上更新
    }
}

3.点修改:

4.区间查询:

拆分和拼凑的思想。

从根节点进入,如果该节点的区间被所查询的区间覆盖了,就直接返回sum ,否则根据左右子节点的重叠情况去往下去递归

 5.区间修改:

难点在于理解懒惰修改,懒惰标记

完整代码:

树状数组:线段树阉割掉了一些点,空间比线段树小,时间一样,维护具有结合律和可拆分信息,如加法(和) 、乘法 (积)、异或等。树状数组能解决的问题是线段树能解决的问题的子集。

性能:代码短,时间常数小

要记住他的三个基本操作 lowbit,add(向后),query(向前)

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

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

int query(int x)
{
    int res = 0;
    while (x) res += tr[x],x -= lowbit(x);
    return res;
}


http://www.kler.cn/a/416417.html

相关文章:

  • OpenAI浅聊爬虫
  • # issue 7 TCP回声服务器和客户端
  • RPA:电商订单处理自动化
  • Rust format失败
  • 在Java中使用Apache POI导入导出Excel(二)
  • Milvus 2.5:全文检索上线,标量过滤提速,易用性再突破!
  • JS-对象-DOM-案例
  • request和websocket
  • python自动化测开面试题汇总(持续更新)
  • 【SpringBoot问题】IDEA中用Service窗口展示所有服务及端口的办法
  • 民宿住宿管理系统|Java|SSM|JSP| 前后端分离
  • 使用zabbix监控k8s
  • C#读取本地图像的方法总结
  • 大米中的虫子检测-检测储藏的大米中是否有虫子 支持YOLO,VOC,COCO格式标注,4070张图片的数据集
  • 爬虫获取的数据如何有效分析以支持商业决策?
  • C/C++链接数据库(MySQL)超级详细指南
  • IDEA好用插件
  • SpringCloud框架学习(第六部分:Sentinel实现熔断与限流)
  • 消息称三星正与 OpenAI 洽谈,有望令 Galaxy AI 整合ChatGPT,三星都要和chatgpt合作了,你会使用chatgpt了吗?
  • 【Docker】Docker配置远程访问