线段树和树状数组

📟作者主页:慢热的陕西人

🌴专栏链接:力扣刷题日记

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

文章目录

  • 树状数组和线段树
    • 1.树状数组
      • 1.1动态求连续区间和
      • 1.2数星星
    • 2.线段树
      • 2.1动态求连续区间和
      • 2.2数列区间最大值

树状数组和线段树

1.树状数组

image-20240322152045076

1.1动态求连续区间和

链接:1264. 动态求连续区间和 - AcWing题库

三个核心函数:

  • lowbit(x):用于计算x的二进制的最后一个1在第几位(从1开始算)
  • add(i, v):对树状数组中的第i个位置+v
  • query(i):计算原数组的s[i]
#include<iostream>
using namespace std;
const int N = 100010;

int a[N], tr[N];

int n, m;

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

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

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

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    //初始化,将原数组的每个值加到树状数组里即可
    for(int i = 1; i <= n; ++i) add(i, a[i]);
    
    //处理m次询问
    for(int i = 0; i < m; ++i)
    {
        int k, x, y;
        cin >> k >> x >> y;
        if(k) add(x, y);
        //计算区间和
        else printf("%d\n", query(y) - query(x - 1));
    }
    
    return 0;
}

1.2数星星

链接:1265. 数星星 - AcWing题库

思路:因为输入的顺序,可以保证在当前星星之前的星星都是纵坐标小于当前星星的,那么我们只需要判断有多少个横坐标小于当前的星星的横坐标,那么就表示该星星是几等级的。因此我们只需要将横坐标的数据用一个树状数组维护起来,方便我们去修改和求值。

注意:因为树状数组的下标是从1开始的,那么我们每次读进来的树都要对横坐标+1;

#include<cstdio>

const int N = 32010;

int tr[N], level[N];

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

void add(int x)
{
    for(int i = x; i < N; i += lowbit(i)) tr[i]++;
}

int sum(int x)
{
    int res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tr[i];

    return res;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        x++;
        level[sum(x)]++;
        add(x);
    }
    
    for(int i = 0; i < n; ++i) printf("%d\n", level[i]);
    
    return 0;
}

2.线段树

image-20240324121751427

操作一:单点修改O(logN)

递归直到叶节点,将对应的节点值修改,然后回溯的去算父节点的和(等于两个子节点的和)直到根节点。

操作二:区间查询O(logN)

区间查询就是问某一个区间的和是多少,递归和要查询的区间有交集的节点,若是当前的节点被区间完全包含那么就返回当前区间的值,否则继续向下递归。

主要函数

①pushup:

用子节点信息,更新当前节点信息。

②build:

在一段区间上初始化线段树

③modify:

修改操作

④query:

区间查询

2.1动态求连续区间和

相对复杂一些,注意处理边界和初始化问题,以及原数组从1开始填写。

#include<iostream>

const int N = 100010;

int w[N];
int n, m;
struct Node
{
    int l, r;
    int sum;
}tr[4 * N];

void pushup(int u)
{
    tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

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);
        //计算当前节点的sum值
        pushup(u);
    }
}

//修改x位置的值加v
void modify(int u, int x, int v)
{
    //当遍历到叶节点,那么直接对该节点上的值+V
    if(tr[u].l == tr[u].r) tr[u].sum += v;
    else
    {
        int mid = tr[u].l + tr[u].r >> 1;
        //在左子树
        if(x <= mid) modify(u << 1, x, v);
        else modify(u << 1 | 1, x, v);
        pushup(u);
    }
}

int query(int u, int l, int r)
{
    //若是当前的节点包含在请求范围内,那么直接返回值
    if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
    //若是有交集,继续向下遍历
    int mid = tr[u].l + tr[u].r >> 1;
    int sum = 0;
    if(l <= mid) sum = query(u << 1, l, r);
    if(mid < r) sum += query(u << 1 | 1, l, r);
    return sum;
}

int main()
{
    scanf("%d%d", &n, &m);
    //为了和线段树一致,从下标为1开始
    for(int i = 1; i <= n; ++i) scanf("%d", &w[i]);
    build(1, 1, n);
    while(m--)
    {
        int k, a, b;
        scanf("%d%d%d", &k, &a, &b);
        if(k != 0) modify(1, a, b);
        else printf("%d\n", query(1, a, b));
    }
    
    return 0;
}

2.2数列区间最大值

链接:1270. 数列区间最大值 - AcWing题库

思路:我们只需要将原本节点存区间和的数据改为存区间最大值即可,然后其他代码非常类似。

但其实线段树的执行效率相对较低所以时间会慢一些。

#include<iostream>
#include<algorithm>
#include<climits>

using namespace std;

int n, m;

const int N = 100010;

int w[N];

struct Node
{
    int l, r;
    int maxv;
}tr[N * 4];

void build(int u, int l, int r)
{
    //当build到叶节点的时候直接赋值
    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].maxv = max(tr[u << 1].maxv, tr[u << 1 | 1].maxv);
    }
}

int query(int u, int l, int r)
{
    if(tr[u].l >= l && tr[u].r <= r) return tr[u].maxv;
    int mid = tr[u].l + tr[u].r >> 1;
    int maxv = INT_MIN;
    if(l <= mid) maxv = query(u << 1, l, r);
    if(r > mid) maxv = max(maxv, query(u << 1 | 1, l, r));
    return maxv;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1; i <=n; ++i) scanf("%d", &w[i]);
    build(1, 1, n);
    
    int l, r;
    while(m--)
    {
        scanf("%d%d", &l, &r);
        printf("%d\n", query(1, l, r));
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/483855.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c#矩阵求逆

目录 一、矩阵求逆的数学方法 1、伴随矩阵法 2、初等变换法 3、分块矩阵法 4、定义法 二、矩阵求逆C#代码 1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵 &#xff08;1&#xff09;伴随矩阵数学方法 &#xff08;2&#xff09;代码 &#xff08;3&#xff09;计算 2、对…

Unity Shader

练习项目链接 1. Shader 介绍 Shader其实就是专门用来渲染图形的一段代码&#xff0c;通过shader&#xff0c;可以自定义显卡渲染画面的算法&#xff0c;使画面达到我们想要的效果。小到每一个像素点&#xff0c;大到整个屏幕&#xff0c;比如下面这个比较常见的效果。 2. Sh…

javaSwing宿舍管理系统(三个角色)

一、 简介 宿舍管理系统是一个针对学校宿舍管理的软件系统&#xff0c;旨在方便学生、宿管和管理员进行宿舍信息管理、学生信息管理以及宿舍评比等操作。该系统使用 Java Swing 进行界面设计&#xff0c;分为三个角色&#xff1a;管理员、宿管和学生。 二、 功能模块 2.1 管…

RK3568平台 iperf3测试网络性能

一.iperf3简介 iperf是一款开源的网络性能测试工具&#xff0c;主要用于测量TCP和UDP带宽性能。它可以在不同的操作系统上运行&#xff0c;包括Windows、Linux、macOS等。iperf具有简单易用、功能强大、高度可配置等特点&#xff0c;广泛应用于网络性能测试、网络故障诊断和网…

深度学习绘制热力图heatmap、使模型具有可解释性

思路 获取想要解释的那一层的特征图&#xff0c;然后根据特征图梯度计算出权重值&#xff0c;加在原图上面。 Demo 加上类激活(cam) 可以看到&#xff0c;cam将模型认为有利于分类的特征标注了出来。 下面以ResNet50为例: Trick: 使用 for i in model._modules.items():可以…

二十三 超级数据查看器 讲解稿 设置

二十三 超级数据查看器 讲解稿 设置 ​点击此处 以新页面 打开B站 播放当前教学视频 点击访问app下载页面 百度手机助手 下载地址 大家好&#xff0c;这节课我们讲一下&#xff0c;超级数据查看器的设置功能。 首先&#xff0c;我们打开超级数据查看器&#xff0c; 我…

2023年全国青少年信息素养大赛(python)初赛真题

选择题&#xff08;每题5分&#xff0c;共20题&#xff0c;满分100分&#xff09; 1、关于列表的索引&#xff0c;下列说法正确的是&#xff1f; A&#xff0e;列表的索引从0开始 B&#xff0e;列表的索引从1开始 C&#xff0e;列表中可能存在两个元素的索引一致 D&#xff0…

第四百一十九回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义标题栏"相关的内容&#xff0c;本章回中将介绍自定义Action菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里提到的…

web自动化3-pytest前后置夹具

一、pytest前后置&#xff08;夹具&#xff09;-fixture 夹具的作用&#xff1a;在用例执行之前和之后&#xff0c;需要做的准备工作和收尾工作。 用于固定测试环境&#xff0c;以及清理回收资源。 举个例子&#xff1a;访问一个被测页面-登录页面&#xff0c;执行测试用例过…

SpringCloud-Gateway服务网关

一、网关介绍 1. 为什么需要网关 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由 权限控制 限流 架构图&#xff1a; 权限控制&#xff1a;网关作为微服务入口&#xff0c;需要校验用户是是否有请求资格&am…

算法-双指针

目录 1、双指针遍历分割:避免开空间&#xff0c;原地处理 2、快慢指针&#xff1a;循环条件下的判断 3、左右指针&#xff08;对撞指针&#xff09;&#xff1a;分析具有单调性&#xff0c;避免重复计算 双指针又分为双指针遍历分割&#xff0c;快慢指针和左右指针 1、双指…

深度学习 tablent表格识别实践记录

下载代码&#xff1a;https://github.com/asagar60/TableNet-pytorch 下载模型&#xff1a;https://drive.usercontent.google.com/download?id13eDDMHbxHaeBbkIsQ7RSgyaf6DSx9io1&exportdownload&confirmt&uuid1bf2e85f-5a4f-4ce8-976c-395d865a3c37 原理&#…

C# 将 Word 转文本存储到数据库并进行管理

目录 功能需求 范例运行环境 设计数据表 关键代码 组件库引入 Word文件内容转文本 上传及保存举例 得到文件Byte[]数据方法 查询并下载Word文件 总结 功能需求 将 WORD 文件的二进制信息存储到数据库里&#xff0c;即方便了统一管理文件&#xff0c;又可以实行权限控…

查看文件内容的指令:cat,tac,nl,more,less,head,tail,写入文件:echo

目录 cat 介绍 输入重定向 选项 -b -n -s tac 介绍 输入重定向 nl 介绍 示例 more 介绍 选项 less 介绍 搜索文本 选项 head 介绍 示例 选项 -n tail 介绍 示例 选项 echo 介绍 输出重定向 追加重定向 cat 介绍 将标准输入(键盘输入)的内容打…

【微服务】Gateway服务网关

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;微服务 ⛺️稳中求进&#xff0c;晒太阳 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响…

单目深度估计基础理论和论文学习总结

单目深度估计基础理论和论文学习总结 一、背景知识&#xff1a; 三维刚体运动的数学表示&#xff1a;旋转平移矩阵、旋转向量、欧拉角、四元数、轴角模型、齐次坐标、各种变换等 照相机模型&#xff1a;单目/双目模型&#xff0c;单目中的世界坐标系/相机坐标系/图像坐标系的…

MySQL表的增删改查---多表查询和联合查询

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

保研复习概率论1

1.什么是随机试验&#xff08;random trial&#xff09;&#xff1f; 如果一个试验满足试验可以在相同的条件下重复进行、试验所有可能结果明确可知&#xff08;或者是可知这个范围&#xff09;、每一次试验前会出现哪个结果事先并不确定&#xff0c;那么试验称为随机试验。 …

ssm+vue的消防物资存储系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的消防物资存储系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

PyQT5学习--新建窗体模板

目录 1 Dialog 2 Main Window 3 Widget Dialog 模板&#xff0c;基于 QDialog 类的窗体&#xff0c;具有一般对话框的特性&#xff0c;如可以模态显示、具有返回值等。 Main Window 模板&#xff0c;基于 QMainWindow 类的窗体&#xff0c;具有主窗口的特性&#xff0c;窗口…