AcWing 245. 你能回答这些问题吗(线段树)

news2025/6/17 4:33:49

AcWing 245. 你能回答这些问题吗(线段树)

  • 一、题目
  • 二、分析
    • 1、节点定义
    • 2、函数分析
      • (1)pushup函数
      • (2)build函数
      • (3)modify函数
      • (4)query函数
  • 三、代码

一、题目

AcWing 246. 区间最大公约数(线段树)

二、分析

1、节点定义

我们肯定要维护是区间的左右端点。另外,根据题目的询问,我们还要去记录一下该区间的最大子段和。但是仅仅记录这三个就够了吗?

当我们无法确定我们的结构定义是否正确的时候,我们就要想一想,根据我们左右子节点中维护的数据能否更新出父节点的最大子段和?答案是不一定。

假设除了左右端点外,我们只维护了一个区间最大子段和。

在这里插入图片描述
假设我们的红色区间是我们父节点所代表的区间的最大子段和。那么很明显,由于这个红线所覆盖的区间也在左子节点中,所以可以直接从子节点更新过来,如果这个红线在右侧也同理。

但是还有一种情况,就是这个红线横跨两个区间。(如下图所示)

在这里插入图片描述
此时我们发现,父节点所代表的区间的最大子段和等于左孩子的最大后缀和加上右子树的最大前缀和。

也就是说,我们想求出当前节点的所代表区间的最大子段和,就需要再去维护子区间的最大前缀和以及最大后缀和。

好了,接下来最大子段和的问题解决了,但又衍生出了新的问题:如何维护最大的前缀和与后缀和?

我们还是去画图:
在这里插入图片描述
如果这个节点的最大前缀和没有超过中间点的话,那么当前节点的最大前缀和就等于左子树的最大前缀和。但是如果超过了呢?
在这里插入图片描述
如果超过了的话,我们的最大前缀和就等于左孩子的区间和加上右孩子的最大前缀和。

所以为了及时的更新出最大前缀和与后缀和,我们还需要去维护一下区间和。

综上所述,我们的节点定义如下:

struct Node
{
	int l, r;
	int lsum;
	int rsum;
	int tsum;
	int sum;
}tre[N * 4];

2、函数分析

(1)pushup函数

这个函数的作用是利用两个子节点维护的信息去更新父节点维护的信息。函数内容即将刚刚的分析过程转化为代码即可。

void pushup(Node & u, Node & ls, Node & rs)
{
	u.sum =  ls.sum + rs.sum;
	u.lsum = max(ls.lsum, ls.sum + rs.lsum);
	u.rsum = max(rs.rsum, rs.sum + ls.rsum);
	u.tsum = max(max(ls.tsum, rs.tsum), ls.rsum + rs.lsum);
}

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

(2)build函数

这个函数的作用是在一开始的时候,利用初始数组去建立我们的线段树。建树的过程只需要不断地递归即可,同时当回溯到当前状态时,说明该节点的子树都已经建好了,此时需要调用我们的 p u s h u p pushup pushup函数去利用子节点更新当前节点。

void build(int u, int l, int r)
{
	if(l == r)
	{
		tre[u] = {l, r, a[l], a[l], a[l], a[l]};
		return;
	}
	else
	{
	    tre[u] = {l, r};
		int mid = l + r >> 1;
		build(u << 1, l, mid);
		build(u << 1 | 1, mid + 1, r);
		pushup(u);
		return;
	}

}

(3)modify函数

这个函数的作用是实现题干中的单点修改操作,我们首先要递归到叶子节点,修改叶子节点后,在回溯的过程利用 p u s h u p pushup pushup来更新父节点。

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

(4)query函数

假设我们查询的是下面的红色区间,那么最终我们的递归函数会查到子树中的蓝色区间。
当我们查到这些蓝色区间后,我们需要通过这些蓝色的区间维护出红色区间的答案。因此,我们可以将这些蓝色区间看作红色区间的子节点,然后通过子节点更新出当前红色区间的答案,该操作恰好就是我们的 p u s h u p pushup pushup函数。

在这里插入图片描述

Node query(int u, int l, int r)
{
	if(tre[u].l >= l && tre[u].r <= r)
		return tre[u];
	else
	{
		int mid = tre[u].l + tre[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 left = query(u << 1, l, r);
			auto right = query(u << 1 | 1, l, r);
			Node res;
			pushup(res, left, right);
			return res;
		}
	}
}

三、代码

#include<bits/stdc++.h>
#define endl '\n'
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 5e5 + 10;
int a[N];
int n, m;
struct Node
{
	int l, r;
	int lsum;
	int rsum;
	int tsum;
	int sum;
}tre[N * 4];

void pushup(Node & u, Node & ls, Node & rs)
{
	u.sum =  ls.sum + rs.sum;
	u.lsum = max(ls.lsum, ls.sum + rs.lsum);
	u.rsum = max(rs.rsum, rs.sum + ls.rsum);
	u.tsum = max(max(ls.tsum, rs.tsum), ls.rsum + rs.lsum);
}

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

void build(int u, int l, int r)
{
	if(l == r)
	{
		tre[u] = {l, r, a[l], a[l], a[l], a[l]};
		return;
	}
	else
	{
	    tre[u] = {l, r};
		int mid = l + r >> 1;
		build(u << 1, l, mid);
		build(u << 1 | 1, mid + 1, r);
		pushup(u);
		return;
	}

}

Node query(int u, int l, int r)
{
	if(tre[u].l >= l && tre[u].r <= r)
		return tre[u];
	else
	{
		int mid = tre[u].l + tre[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 left = query(u << 1, l, r);
			auto right = query(u << 1 | 1, l, r);
			Node res;
			pushup(res, left, right);
			return res;
		}
	}
}

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

void solve()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ )
		cin >> a[i];
	build(1, 1, n);
	while(m --)
	{
		int opt, x, y;
		cin >> opt >> x >> y;
		if(opt == 1)
		{
		    if(x > y)
			    swap(x, y);
			cout << query(1, x, y).tsum << endl;
		}
		else
			modify(1, x, y);
	}
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	solve();
}

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

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

相关文章

COM 对象析构函数是非常敏感的函数

如果你试图在 COM 对象的析构函数中做太多事情&#xff0c;你会发现自己有麻烦。 此话怎讲? 举个例子&#xff0c;如果析构函数将自身引用交给其他函数&#xff0c;则这些函数可能会决定调用 IUnknown::AddRef 和 IUnknown::Release 方法作为其内部操作的一部分。考察下面的…

解码行业新趋势:2023晶球益生菌与肠内营养健康高峰论坛圆满落幕

后疫情时代&#xff0c;国人自身健康管理意识日益提高&#xff0c;越来越多的人认识到到微生物组、营养吸收与免疫健康的密切联系&#xff0c;并逐渐认可微生态和肠内营养在临床应用过程中的积极作用&#xff0c;使得营养治疗研究成果进一步落地转化。消费升级新时代&#xff0…

项目6:实现数据字典的展示与缓存

项目6&#xff1a;实现数据字典的展示与缓存 1.数据字典如何展示&#xff1f; 2.前后端如何设计&#xff1f; 3.前端设计代码&#xff1f; 4.后端设计代码&#xff1f; 5.实现数据字典缓存到redis 项目6&#xff1a;实现数据字典的展示与缓存 1.数据字典如何展示&#xf…

WEB攻防-通用漏洞PHP反序列化POP链构造魔术方法原生类

目录 一、序列化和反序列化 二、为什么会出现反序列化漏洞 三、序列化和反序列化演示 <演示一> <演示二> <演示二> 四、漏洞出现演示 <演示一> <演示二> 四、ctfshow靶场真题实操 <真题一> <真题二> <真题三> &l…

C++入门到入土(一)

C语言中&#xff0c;我们这样定义&#xff0c;输出100。 因为局部作用域的访问权限大于全局作用域的。 当我们加入头文件#include <time.h>的时候&#xff0c;就会报错 看报错&#xff0c;我们也知道&#xff0c;time重定义&#xff0c;因为我们头文件time.h里面有time函…

验证码识别过程中切割图片的几种方案

目录 方案一&#xff1a;图片均分 方案二&#xff1a;寻找轮廓并截取 方案三&#xff1a;聚类算法 方案四&#xff1a;垂直投影法 源码下载 在用机器学习识别验证码的过程中&#xff0c;我们通常会选择把验证码中的各个字符切割出来然后单独识别&#xff0c;切割质量会直接…

JS Hook 基本使用

前言 Hook技术也叫钩子函数&#xff0c;功能是把网站的代码拉出来&#xff0c;改成我们自己想执行的代码片段&#xff0c;简单来说就是可以控制执行函数的入参和出参&#xff1b; 一、资源下载 编程猫插件&#xff1a;https://pan.baidu.com/s/1SP8xHoDpugssFRpu-nLxPw?pwdz…

ARM 编译器 Arm Compiler for Embedded 6 相关工具链简介

目录 1, Introduction to Arm Compiler 6 1.1 armclang 1.2 armasm 1.3 armlink 1.4 armar 1.5 fromelf 1.6 Arm C libraries 1.7 Arm C libraries 1,8 Application development &#xff0c;ARM程序开发流程 2&#xff0c;ARM 编译器 5和ARM 编译器 6的兼容性 3&…

Opencv项目实战:22 物体颜色识别并框选

目录 0、项目介绍 1、效果展示 2、项目搭建 3、项目代码展示与部分讲解 Color_trackbar.py bgr_detector.py test.py 4、项目资源 5、项目总结 0、项目介绍 本次项目要完成的是对物体颜色的识别并框选&#xff0c;有如下功能&#xff1a; &#xff08;1&#xff09;…

【权限提升】Linux Sudo权限提升漏洞(CVE-2023-22809)

文章目录前言一、Sudo介绍二、漏洞概述三、漏洞成因四、漏洞分析五、影响版本六、本地复现七、修复建议前言 Sudo存在权限提升漏洞,攻击者可过特定的payload获取服务器ROOT权限 一、Sudo介绍 sudo (su " do")允许系统管理员将权限委托给某些用户(或用户组),能够以…

网络安全与防御

1. 什么是IDS&#xff1f; IDS(入侵检测系统)&#xff1a;入侵检测是防火墙的合理补充&#xff0c;帮助系统对付网络攻击&#xff0c;扩展了系统管理员的安全管理能力&#xff0c;提高了信息安全基础结构的完整性。主要针对防火墙涉及不到的部分进行检测。 入侵检测主要面对的…

ChatGPT技术原理、研究框架,应用实践及发展趋势(附166份报告)

​ 一、AI框架重要性日益突显&#xff0c;框架技术发展进入繁荣期&#xff0c;国内AI框架技术加速发展&#xff1a; 1、AI框架作为衔接数据和模型的重要桥梁&#xff0c;发展进入繁荣期&#xff0c;国内外框架功能及性能加速迭代&#xff1b; 2、Pytorch、Tensorflow占据AI框…

5.2 中心极限定理

学习目标&#xff1a; 要学习中心极限定理&#xff0c;我会采取以下几个步骤&#xff1a; 学习基本概念&#xff1a;了解什么是随机变量、样本、总体、概率密度函数等基本概念&#xff0c;为学习中心极限定理打下基础&#xff1b;学习正态分布&#xff1a;中心极限定理的核心…

【JavaEE】计算机组成以及操作系统(进程)的基本知识

目录 前言 1、计算机基本组成 1.1、存储器 2、操作系统 2.1、 进程&#xff08;任务&#xff09;的概念 2.2、进程的管理 2.2.1、进程控制块PCB&#xff08;process control block&#xff09; 2.3、CPU分配&#xff08;进程调度&#xff09; 2.3.1、并发 2.3.2、并…

string容器

1、string的构造和赋值 #include #include using namespace std; void test01() { string str1(“hello world”); //使用字符串初始化 cout<<str1<<endl; string str2(5,‘A’); //使用 n 个字符串是初始化 cout<<str2<<endl; string str3 str2; …

深度学习数据集—水果数据集大合集

近期整理的各类水果&#xff08;包括干果&#xff09;数据集&#xff0c;分享给大家。 1、8类水果图片数据集&#xff08;每类100张图片左右&#xff09;[橘子&#xff0c;菠萝&#xff0c;苹果&#xff0c;木瓜&#xff0c;火龙果&#xff0c;香蕉&#xff0c;樱桃&#xff0…

系统升级 | RK3568开发平台成功搭载SylixOS国产实时操作系统

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

【GPT4】微软 GPT-4 测试报告(5)与外界环境的交互能力

欢迎关注【youcans的AGI学习笔记】原创作品 微软 GPT-4 测试报告&#xff08;1&#xff09;总体介绍 微软 GPT-4 测试报告&#xff08;2&#xff09;多模态与跨学科能力 微软 GPT-4 测试报告&#xff08;3&#xff09;编程能力 微软 GPT-4 测试报告&#xff08;4&#xff09;数…

被裁了,39 岁阿里 P9,攒下 1.5 亿....

今天刷知乎&#xff0c;在问题 “40 岁因为财务自由决定不上班的人&#xff0c;个人资产总和到底有多少” 下看到一位阿里 P9 的匿名回答让我狠狠的酸了一把~ 这刚刚失业的四十岁高级码农自曝了自己的人生经历&#xff0c;作为一名“阿里 P9”的程序员&#xff0c;他讲述了自己…

重庆理工大学教授程平:智能会计时代,应充分发挥数据资产的价值

近日&#xff0c;由用友主办的「智能会计 价值财务」2023企业数智化财务创新峰会北京站在北京国家会计学院圆满举办&#xff01;来自知名院校的专家学者、央国企等大型企业财务领路人、以及权威财经媒体相约北京国家会计学院&#xff0c;一同见证“智能会计”新时代的到来&…