AcWing245. 你能回答这些问题吗 线段树详解

news2025/7/18 11:59:04

3.2线段树

在这里插入图片描述

例题分析

245. 你能回答这些问题吗 - AcWing题库

**题意:**给一条序列,如何动态维护区间的最大子段和,包括询问某区间的最大字段和和修改某个数。

分析:线段树struct保留什么信息。能否通过左右儿子的这些信息求出父节点的所有信息。

首先毋庸置疑的是左右端点和最大连续子段和。

struct node{
	int l,r;
	int tmax;
}

然后我们思考,能不能得到父节点的信息。

​ 如图,假设我们已知左右孩子的最大子段和,同时假设父节点的最大字段和为图中绿色区域,我们发现,父节点的最大连续子段和可能是跨区间的,我们没办法通过孩子的信息得到父亲的信息,所以我们考虑添加维护的信息。

我们维护每个区间的最大前缀和和最大后缀和,如下图,横跨整个区间的子段和可以通过左边的最大后缀和加上右边的最大前缀和得到。

此时我们的结构体变成了这样:

struct node{
	int l,r;
	int tmax;//区间的最大字段和
	int lmax;//区间的最大前缀和
	int rmax;//区间的最大后缀和
}

那我们再回到刚才的思考,通过这些信息如何得到父节点的信息。

​ 那么,结合三个信息,我们可以用三个值(左儿子的最大子段和、右儿子的最大子段和、左儿子的最大后缀和加右儿子的最大前缀和)取max来得到。这里信息全面吗?答案是全面的,不过是对于区间最大子段和来说;假设最大子段和在左区间,那么(如下图)1、2、3区间(前缀、中间、后缀)能够完全表示,4、5、6同理,除了这些情况,再加上跨区间的情况,那么这些情况取max就是确定的最大值。

接下来我们再思考,我们新加入的两个信息是否能通过儿子节点求出来, 假设我们的最大前缀和是跨区间的时候,那么情况变成了这样,所以我们还需要加一个信息:区间和。

而区间和我们是可以直接求的,因此,我们每个信息都能得到了,分析完毕。

struct node{
	int l,r;
	int tmax;//区间的最大字段和
	int lmax;//区间的最大前缀和
	int rmax;//区间的最大后缀和
	int sum;//区间和
}

思考模式:首先我们想如何得到我们想要的答案,当添加了想要的信息之后,还要思考如何得到想要的信息,最后直到全部信息都能通过左右孩子得到。

参考代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 5e6 + 5;
vector<int> ve(N);
int n, k;

struct node {
    int l, r;
   	int tmax;//区间的最大字段和
	int lmax;//区间的最大前缀和
	int rmax;//区间的最大后缀和
	int sum;//区间和
} tr[4 * N];

void pushup(node& u, node& l, node& r) {//函数重载
    u.tmax = max(max(l.tmax, r.tmax), l.rmax + r.lmax);
    u.lmax = max(l.lmax, l.sum + r.lmax);
    u.rmax = max(r.rmax, r.sum + l.rmax);
    u.sum = l.sum + r.sum;
}

void pushup(int u) {
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r) {
    if (l == r) {
        tr[u]={l,r,ve[l],ve[l],ve[l],ve[l]};//到子节点直接存下所有信息
        return;
    }
    tr[u] = {l, r};
    int mid = l + r >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);//这里想要pushup
}

node query(int u, int l, int r) {
    if (tr[u].l >= l && tr[u].r <= r)
        return tr[u];
    int mid = tr[u].l + tr[u].r >> 1;
    if (r <= mid)
        return query(u << 1, l, r);//答案完全在左区间
    else if (l > mid)
        return query(u << 1 | 1, l, r);//答案完全在右区间
    else{
        auto R = query(u << 1, l, r);
        auto L=query(u << 1 | 1, l, r); //答案想要左右区间的信息合并才能得到
        node res;
        pushup(res, R, L);//合并左右区间信息
        return res;
    }
}

void modify(int u,int x,int val){
    if(tr[u].l==x&&tr[u].r==x)
        tr[u] = {x,x,val,val,val,val};
    else{
        int mid = tr[u].l + tr[u].r >> 1;
        if(x<=mid)
            modify(u << 1, x, val);
        else
            modify(u << 1 | 1, x, val);
        pushup(u);
    }
}

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> ve[i];
    }
    //cout << "x" <<endl;
    build(1, 1, n);
    //cout << "x" << endl;
    for (int i = 1; i <= k; i++) {
        int q;
        cin >> q;
        if (q == 1) {
            int l, r;
            cin >> l >> r;
            if(l>r)
                swap(l, r);
            cout<<query(1, l, r).tmax<<endl;
        } else {
            int x, y;
            cin >> x >> y;
            modify(1, x, y);
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HA RabbitMQ on K8s helm部署实战

RabbitMQ on K8s helm部署实战获取helm chart修改必要参数外部如何访问&#xff1f;安装rabbitmq登录管理界面导入mq metadata优化helm chart 生成的statefuleset yamlhelm chart 生成的pod yaml调整mq log等级promethrus 监控mq配置prometheus采集metrics查看prometheus rabbi…

零基础借助arpl自动编译工具在一小时之内将旧笔记本、嵌入式设备等改造成黑群辉

文章目录1. 前言2. 编译2.1. 到GitHub把编译引导需要用的img文件下载到电脑上2.2. 将下载下来的IMG文件解压为img文件&#xff0c;用rufus或者其他写盘工具写入到U盘中&#xff0c;2.3. 进行引导启动2.4. 获得编译系统的IP地址2.5. 在同一局域网下&#xff0c;打开这个IP地址2.…

Java学习笔记 --- IO流

一、文件 什么是文件 文件是保存数据的地方 文件流 文件在程序中是以流的形式来操作的 流&#xff1a;数据在数据源&#xff08;文件&#xff09;和程序&#xff08;内存&#xff09;之间经历的路径 输入流&#xff1a;数据从数据源&#xff08;文件&#xff09;到程序&a…

Pr:文本面板之转录文本

Pr菜单&#xff1a;窗口/文本Text在文本面板的转录文本 Transcript选项卡中&#xff0c;单击“转录序列” Transcribe sequence按钮&#xff0c;然后设置好选项并进行语音到文本的转录。创建转录文本对话框Create transcript语言Language选择视频中语音所使用的语言。也可选择不…

2.7 基本放大电路的派生电路

在实际应用中&#xff0c;为了进一步改善放大电路的性能&#xff0c;可用多只晶体管构成复合管来取代基本电路中的一只晶体管&#xff1b;也可根据需要将两种基本接法组合起来&#xff0c;以得到多方面性能俱佳的放大电路。 一、复合管放大电路 1、复合管 &#xff08;1&…

【路径规划】(1) Dijkstra 算法求解最短路,附python完整代码

好久不见&#xff0c;我又回来了&#xff0c;这段时间把路径规划的一系列算法整理一下&#xff0c;感兴趣的点个关注。今天介绍一下机器人路径规划算法中最基础的 Dijkstra 算法&#xff0c;文末有 python 完整代码&#xff0c;那我们开始吧。 1. 算法介绍 1959 年&#xff0c…

Bugku MISC 啊哒 贝斯手

啊哒 下载文件&#xff0c;解压后发现是一张图片&#xff0c;用010editor打开 可以看到里面有个flag.txt 。使用kali中的binwalk进行文件分离 查看文件 &#xff1a; binwalk ada.jpg 分离文件 &#xff1a; binwalk -e ada.jpg --run-asroot 打开分离后的文件夹 可以看到有一…

T288401 B-莲子的机械动力学

专攻超统一物理学的莲子&#xff0c;对机械结构的运动颇有了解。如下图所示&#xff0c;是一个三进制加法计算器的&#xff08;超简化&#xff09;示意图。 一个四位的三进制整数&#xff0c;从低到高位&#xff0c;标为 x_1,x_2,x_3,x_4x1​,x2​,x3​,x4​。换言之&#xff0…

第八章《Java高级语法》第12节:Lambda表达式

Lambda 表达式是 JDK8 的一个新特性,它可以定义大部分的匿名内部类,从而让程序员能写出更优雅的Java代码,尤其在集合的各种操作中可以极大地优化代码结构。 8.12.1 认识Lambda表达式 一个接口的实现类可以被定义为匿名类。经过大量实践,人们发现定义一个接口的匿名实现类…

ADAU1860调试心得(8)FASTDSP-0 通道输入

这个程序&#xff0c;我们正式要用到 DSP 了&#xff0c;ADC 进来的数据&#xff0c;经过 FASTDSP 的算法进行处理&#xff0c;再 送给 DAC 推到耳机&#xff0c;通道我们输入 0 到输出为例&#xff0c;还是先做直通&#xff0c;DSP 路过一下&#xff0c;并不做处理。 首先是寄…

WebStorm创建第一个Express项目

WebStorm创建Express项目步骤如下&#xff1a; 1、在WebStorm创建项目 选择项目存储位置&#xff0c;然后点击create&#xff0c;再选择创建的窗口&#xff0c;一般都是创建在this window上 2、进入窗口会终端会开始下载Express项目所需要的文件&#xff0c;我们等到出现如下图…

C++中的多态(下)

&#x1f9f8;&#x1f9f8;&#x1f9f8;各位大佬大家好&#xff0c;我是猪皮兄弟&#x1f9f8;&#x1f9f8;&#x1f9f8; 文章目录一、C11当中的final和overridefinaloverride二、重载&重定义(隐藏)&重写(覆盖)三、抽象类&#xff08;接口类&#xff09;四、接口继…

Hive数据定义语言DDL

文章目录1 Apache Hive客户端使用2 Hive编译工具3 Hive SQL DDL建表基础语法3.1 Hive数据类型详解3.2 Hive读写文件机制3.3 Hive数据存储路径3.4 案例--王者荣耀数据Hive建表映射4 Hive SQL DDL建表高阶语法4.1 Hive 内部表、外部表4.2 Hive Partitioned Tables 分区表4.3.1 数…

第九章 堆排序与TOPK问题

第九章&#xff1a;堆排序与TOPK问题一、堆排序&#xff1a;1、思路分析&#xff1a;&#xff08;1&#xff09;建堆&#xff08;2&#xff09;排序2、堆排序模板二、TOPK问题&#xff1a;1、什么是TOPK问题&#xff1f;2、解决方法一、堆排序&#xff1a; 假设我们实现一个小…

【数据结构】二叉树

目录 一、树 1.1树的一些重要概念 1.2树的应用 二、二叉树 2.1概念 2.2两种特殊的二叉树 二叉树的第一个特点 二叉树的第二个特点 二叉树的第三个特点&#xff1a; 2.3二叉树的存储 2.4二叉树的遍历-深度优先搜索&#xff08;二叉树的高度&#xff09;dfs 前序遍历…

Java学习:动态代理

java一、代理模式二、静态代理三、动态代理一、代理模式 代理模式是一种设计模式,能够使得再不修改源目标的情况下,额外扩展源目标的功能。即通过访问源目标的代理类,再由代理类去访问源目标。这样一来,要扩展功能,就无需修改源目标的代码了。只要在代理上增加就可以了 二、静态…

CSAPP学习导航2015

CSAPP学习导航2015为什么要学这个课程前后置前置后置课程资料课程视频课程组成实验&#xff0c;lab*7学完后学习打卡总结为什么要学这个 深入浅出的为我们搭建计算机学习体系&#xff0c;为以后更深入的学习打好基础。 &#xff08;这学学&#xff0c;那学学&#xff0c;所学太…

iwebsec靶场 SQL注入漏洞通关笔记4- sleep注入(时间型盲注)

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入&#xff08;布尔型盲注&#…

语法制导翻译(Syntax-Directed Translation)

语法制导翻译&#xff08;Syntax-Directed Translation&#xff09;语法制导翻译概述语法制导定义&#xff08;SDD&#xff09;文法符号的属性SDD 求值顺序S-SDD 和 L-SDD语法制导翻译方案&#xff08;SDT&#xff09;S-SDD的SDT实现L-SDD的SDT实现在非递归的预测分析过程中进行…

LeetCode HOT 100 —— 32.最长有效括号

题目 给你一个只包含 ‘(’ 和 ‘)’ 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 思路 方法一&#xff1a;动态规划 定义dp[i]表示以下标i结尾的最长有效括号的长度&#xff0c;并全部初始化为0 注意到有效的子串一定是以’…