线段树的懒标记

news2025/1/17 3:43:40

上次看的那个视频讲线段树的时候压根没讲懒标记,然后我今天去写题目直接被薄纱!都是70分,剩下3个节点tml!!!

懒标记

我们在修改一些区间的时候,按照我昨天来学的来修改要改到最下面的叶节点去,可是这样子就没有了线段树的精华的区间修改,这样子我们时间复杂度会大大增加就像这样子

void updata(int arr[], int tree[], int node, int start, int end, int idx, int val)//位置 改变后的数
{
	if (start == end)
	{
		arr[idx] = val;
		tree[node] = val;
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2 + 1;
		int right_node = node * 2 + 2;
		if (idx >= start && idx <= mid)
		{
			updata(arr, tree, left_node, start, mid, idx, val);
		}
		else
		{
			updata(arr, tree, right_node, mid+1, end, idx, val);
		}
		tree[node] = tree[left_node] + tree[right_node];
	}
}

于是我们就引入了懒标记这个东西,简单的来说,就是我们如果是要修改6到9,那么我们可以直接在6到9这个地方加上一个lazy=我们要增加的值,然后我们如果在后面要运用这个节点下面的节点的时候,就把这个lazy下放,这样子我们就可以不需要一定要找到最下面的节点,大大节约了时间复杂度!

 然后就是我写的线段树的题目,不过只有70分(;´༎ຶД༎ຶ`) 

# 【模板】线段树 1

## 题目描述

如题,已知一个数列,你需要进行下面两种操作:

1. 将某区间每一个数加上 $k$。
2. 求出某区间每一个数的和。

## 输入格式

第一行包含两个整数 $n, m$,分别表示该数列数字的个数和操作的总个数。

第二行包含 $n$ 个用空格分隔的整数,其中第 $i$ 个数字表示数列第 $i$ 项的初始值。

接下来 $m$ 行每行包含 $3$ 或 $4$ 个整数,表示一个操作,具体如下:

1. `1 x y k`:将区间 $[x, y]$ 内每个数加上 $k$。
2. `2 x y`:输出区间 $[x, y]$ 内每个数的和。

## 输出格式

输出包含若干行整数,即为所有操作 2 的结果。

## 样例 #1

### 样例输入 #1

```
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
```

### 样例输出 #1

```
11
8
20
```

## 提示

对于 $30\%$ 的数据:$n \le 8$,$m \le 10$。  
对于 $70\%$ 的数据:$n \le {10}^3$,$m \le {10}^4$。  
对于 $100\%$ 的数据:$1 \le n, m \le {10}^5$。

保证任意时刻数列中所有元素的绝对值之和 $\le {10}^{18}$。

**【样例解释】**

![](https://cdn.luogu.com.cn/upload/pic/2251.png)

#include <stdio.h>
void bulid_tree(long long arr[], long long tree[], int node, int start, int end)
{
	if (start == end)
	{
		tree[node] = arr[start];
	}
	else
	{
	    int mid = (start + end) / 2;
	    int left_node = node * 2;
	    int right_node = node * 2+1;
	    bulid_tree(arr, tree, left_node, start, mid);
	    bulid_tree(arr, tree, right_node, mid+1, end);
	    tree[node] = tree[left_node] + tree[right_node];
	}
}
long long qureytree(long long arr[], long long tree[], int node, int start, int end, int L, int R)
{
	if (R<start||L>end)
	{
		return 0;
	}
	if (L <= start && R >= end)
	{
		return tree[node];
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2;
		int right_node = node * 2 + 1;
		long long sum_left = qureytree(arr, tree, left_node, start, mid, L, R);
		long long sum_right= qureytree(arr, tree, right_node, mid+1, end, L, R);
		return sum_left + sum_right;
	}
}
void up_data(long long arr[], long long tree[], int node, int start, int end, int idx, int val)
{
	if (start==end)
	{
		arr[start] = arr[start] + val;
		tree[node] = tree[node] + val;
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2;
		int right_node = node * 2 + 1;
		if (idx >= start && idx <= mid)
		{
			up_data(arr, tree, left_node, start, mid, idx, val);
		}
		else
		{
			up_data(arr, tree, right_node, mid + 1, end, idx, val);
		}
		tree[node] = tree[left_node] + tree[right_node];
	}
}
int main()
{
	long long arr[1000001], tree[1000001];
	int n, m,i;
	int x, y, k, xx;
	//printf("8888");
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++)
	{
		scanf("%lld", &arr[i]);
	}
	bulid_tree(arr, tree, 1, 1, n);
	//printf("%d")
	while (m--)
	{
		scanf("%d", &xx);
		if (xx == 1)
		{
			scanf("%d%d%d", &x, &y, &k);//将区间 [x, y]内每个数加上 k。
			for (i = x; i <= y; i++)
			{
				up_data(arr, tree, 1, 1, n, i, k);
			}
		}
		if (xx == 2)
		{
			//printf("*****");
			scanf("%d%d", &x, &y);//输出区间 [x, y]内每个数的和。
			printf("%lld\n", qureytree(arr, tree, 1, 1, n, x, y));
		}
	}
}

# 【模板】线段树 2

## 题目描述

如题,已知一个数列,你需要进行下面三种操作:

- 将某区间每一个数乘上 $x$

- 将某区间每一个数加上 $x$

- 求出某区间每一个数的和

## 输入格式

第一行包含三个整数 $n,m,p$,分别表示该数列数字的个数、操作的总个数和模数。

第二行包含 $n$ 个用空格分隔的整数,其中第 $i$ 个数字表示数列第 $i$ 项的初始值。

接下来 $m$ 行每行包含若干个整数,表示一个操作,具体如下:

操作 $1$: 格式:`1 x y k`  含义:将区间 $[x,y]$ 内每个数乘上 $k$

操作 $2$: 格式:`2 x y k`  含义:将区间 $[x,y]$ 内每个数加上 $k$

操作 $3$: 格式:`3 x y`  含义:输出区间 $[x,y]$ 内每个数的和对 $p$ 取模所得的结果

## 输出格式

输出包含若干行整数,即为所有操作 $3$ 的结果。

## 样例 #1

### 样例输入 #1

```
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
```

### 样例输出 #1

```
17
2
```

## 提示

【数据范围】

对于 $30\%$ 的数据:$n \le 8$,$m \le 10$   
对于 $70\%$ 的数据:$n \le 10^3 $,$ m \le 10^4$   
对于 $100\%$ 的数据:$ n \le 10^5$,$ m \le 10^5$

除样例外,$p = 571373$

(数据已经过加强^\_^)


样例说明:

 ![](https://cdn.luogu.com.cn/upload/pic/2255.png) 

故输出应为 $17$、$2$( $40 \bmod 38 = 2$ )

#include <stdio.h>
void bulid_tree(long long arr[], long long tree[], int node, int start, int end)
{
	if (start == end)
	{
		tree[node] = arr[start];
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2;
		int right_node = node * 2 + 1;
		bulid_tree(arr, tree, left_node, start, mid);
		bulid_tree(arr, tree, right_node, mid + 1, end);
		tree[node] = tree[left_node] + tree[right_node];
	}
}
long long qureytree(long long arr[], long long tree[], int node, int start, int end, int L, int R)
{
	if (R<start || L>end)
	{
		return 0;
	}
	if (L <= start && R >= end)
	{
		return tree[node];
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2;
		int right_node = node * 2 + 1;
		long long sum_left = qureytree(arr, tree, left_node, start, mid, L, R);
		long long sum_right = qureytree(arr, tree, right_node, mid + 1, end, L, R);
		return sum_left + sum_right;
	}
}
void up_data(long long arr[], long long tree[], int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		arr[start] = arr[start] + val;
		tree[node] = tree[node] + val;
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2;
		int right_node = node * 2 + 1;
		if (idx >= start && idx <= mid)
		{
			up_data(arr, tree, left_node, start, mid, idx, val);
		}
		else
		{
			up_data(arr, tree, right_node, mid + 1, end, idx, val);
		}
		tree[node] = tree[left_node] + tree[right_node];
	}
}
void up_data1(long long arr[], long long tree[], int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		arr[start] = arr[start]*val;
		tree[node] = tree[node]*val;
		//printf("%d\n", tree[node]);
	}
	else
	{
		int mid = (start + end) / 2;
		int left_node = node * 2;
		int right_node = node * 2 + 1;
		if (idx >= start && idx <= mid)
		{
			up_data1(arr, tree, left_node, start, mid, idx, val);
		}
		else
		{
			up_data1(arr, tree, right_node, mid + 1, end, idx, val);
		}
		tree[node] = tree[left_node] + tree[right_node];
	}
}
int main()
{
	long long arr[1000000], tree[1000000],k;
	int n, m, i,p;
	int x, y, xx;
	//printf("8888");
	scanf("%d%d%d", &n, &m,&p);
	for (i = 1; i <= n; i++)
	{
		scanf("%lld", &arr[i]);
	}
	bulid_tree(arr, tree, 1, 1, n);
	//printf("%d")
	while (m--)
	{
		scanf("%d", &xx);
		if (xx == 1)
		{
			scanf("%d%d%lld", &x, &y, &k);
			for (i = x; i <= y; i++)
			{
				up_data1(arr, tree, 1, 1, n, i, k);
			}
		}
		if (xx == 2)
		{
			scanf("%d%d%lld", &x, &y, &k);//将区间 [x, y]内每个数加上 k。
			for (i = x; i <= y; i++)
			{
				up_data(arr, tree, 1, 1, n, i, k);
			}

		}
		if (xx == 3)
		{
			//printf("*****");
			scanf("%d%d", &x, &y);//输出区间 [x, y]内每个数的和。
			printf("%lld\n", qureytree(arr, tree, 1, 1, n, x, y)%p);
		}
	}
}

等我明天把懒标记的代码搞出来!!!拿下这两个题目!!!

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

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

相关文章

Visual Studio如何将UTF-8字符串输出到控制台

解决c语言使用libcurl库时控制台输出中文出现乱码的问题。 字符编码问题一直以来都是Windows系统的诟病&#xff0c;而Visual Studio也是饱受此诟病。由于历史原因&#xff0c;Windows系统对各个不同的国家地区可能采用不同的code page。由于早先Unicode并未发展成熟&#xff0…

Java设计模式之工厂模式

什么是工厂模式 工厂模式就是将创建对象的具体过程和使用过程分开&#xff0c;这样能够使代码更加灵活。 工厂模式主要分为三类&#xff1a; 简单工厂模式工厂方法模式抽象工厂模式 比如在没有工厂的时候&#xff0c;用户需要一台奥迪车&#xff0c;那么就需要用户去创建一台…

【java 多线程】并发设计模式-两阶段终止模式(对interrupt的理解)

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

惊艳!阿里出品“Java全栈进阶宝典”,广度与深度齐头并进

前言 据有关数据统计&#xff0c;目前来看&#xff0c;大大小小的招聘网站上面&#xff0c;Java岗的招聘量仍然是最多的&#xff0c;基本是其他语言的3倍以上&#xff0c;由于目前Java所处的统治级地位&#xff0c;单就数量来看&#xff0c;Java语言实现的系统是海量的&#x…

linux安装MongoDB

环境说明 系统CentOS&#xff1a;CentOS7 mongodb版本 4.2.24 下载 官网下载地址 Download MongoDB Community Server | MongoDB 某云盘 链接&#xff1a;https://pan.baidu.com/s/1G4AC3h5rvz9WM3fx4gJzbA 提取码&#xff1a;ojkl 上传解压 在根目录下创建opt文件夹…

【数据分析之道-基础知识(九)】推导式

文章目录专栏导读1、前言2、列表推导式3、集合推导式4、字典推导式5、元组推导式专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN Python领域新星创作者&#xff0c;专注于分享python领域知识。 ✍ 本文录入于《数据分析之道》&#xff0c;本专栏针对大学生、初级数据分…

C语言学习1--------Visual Studio集成开发环境的搭建

C语言学习1--------Visual Studio集成开发环境的搭建适合初学者适用集成开发环境下载 Visual Studio 2019安装 Visual Studio 2019安装工作负载为C自定义安装位置激活 Visual Studio适合初学者适用集成开发环境 建议初学者适用最新的——Visual Studio 2019为集成开发环境。 部…

【数据库原理 • 五】数据库安全性与完整性

前言 数据库技术是计算机科学技术中发展最快&#xff0c;应用最广的技术之一&#xff0c;它是专门研究如何科学的组织和存储数据&#xff0c;如何高效地获取和处理数据的技术。它已成为各行各业存储数据、管理信息、共享资源和决策支持的最先进&#xff0c;最常用的技术。 当前…

【C++11那些事儿(一)】

文章目录一、C11简介二、列表初始化2.1 C98中{}的初始化问题2.2 C11中的列表初始化三、各种小语法3.1 auto3.2 decltype3.3 nullptr3.4 范围for四、STL中的一些变化五、左/右值引用和移动语义&#xff08;本篇重点&#xff09;5.1 做值引用和右值引用5.2 左值引用与右值引用比较…

【快乐手撕LeetCode题解系列】—— 复制带随机指针的链表

【快乐手撕LeetCode题解系列】—— 复制带随机指针的链表&#x1f60e;前言&#x1f64c;复制带随机指针的链表&#x1f64c;画图分析&#xff1a;&#x1f60d;思路分析&#xff1a;&#x1f60d;源代码分享&#xff1a;&#x1f60d;总结撒花&#x1f49e;&#x1f60e;博客昵…

shell结构化命令中for命令

shell脚本编程系列 for var in list docommands done读取列表中的值 每次遍历值列表时&#xff0c;for命令会将列表中的下一个值赋值给变量 #!/bin/bash# basic for commandfor test in Alabama Alaska Arizona Arkansas California Coloradodoecho The next state is $testdo…

第07章_面向对象编程(进阶)

第07章_面向对象编程(进阶) 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 1. 关键字&#xff1a;this 1.1 this是什么&#xff1f; 在Java中&#xff0c;this关键字不算难理解…

关于图像分割的预处理 transform

目录 1. 介绍 2. 关于分割中的 resize 问题 3. 分割的 transform 3.1 随机缩放 RandomResize 3.2 随机水平翻转 RandomHorizontalFlip 3.3 随机竖直翻转 RandomVerticalFlip 3.4 中心裁剪 RandomCrop 3.5 ToTensor 3.6 normalization 3.7 Compose 4. 预处理结果可视…

WPF mvvm框架Stylet使用教程-基础用法

Stylet框架基础用法 安装Nuget包 在“管理Nuget程序包”中搜索Stylet&#xff0c;查看Stylet包支持的net版本&#xff0c;然后选择第二个Stylet.Start包进行安装&#xff0c;该包会自动安装stylet并且生成基本的配置 注意事项&#xff1a;安装时要把需要安装的程序设为启动项…

第06章_面向对象编程(基础)

第06章_面向对象编程&#xff08;基础&#xff09; 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 学习面向对象内容的三条主线 Java类及类的成员&#xff1a;&#xff08;重点&…

《QT+CGAL网格处理——网格重建》

QT+CGAL网格处理——网格重建 一、重建效果二、代码分析显示代码格式转换彩色网格显示三、后续一、重建效果 二、代码分析 显示 1、依旧采取VTK显示,参照《QT+PCL》; 2、点数据、网格数据依旧采用pcl数据结构,cgal处理完成后转换格式即可 界面参照:

微服务学习-SpringCloud -Nacos (心跳机制及健康检查源码学习)

文章目录心跳机制与健康检查流程图心跳机制与健康检查总结详细源码说明当多个服务进行注册时&#xff0c;如何解决注册表并发冲突问题?心跳机制与健康检查流程图 心跳机制与健康检查总结 微服务在启动注册Nacos时&#xff0c;会创建一个定时任务&#xff0c;定时向服务端发生…

基于文心一言的底层视觉理解,百度网盘把「猫」换成了「黄色的猫」

随着移动互联网的一路狂飙&#xff0c;手机已经成为人们的新器官。出门不带钥匙可以&#xff0c;不带手机却是万万不可以的。而手机上&#xff0c;小小的摄像头也越来越成为各位「vlogger」的口袋魔方。每天有超过数亿的照片和视频被上传到百度网盘中&#xff0c;这些照片和视频…

Nginx 实战-负载均衡

一、负载均衡今天学习一下Nginx的负载均衡。由于传统软件建构的局限性&#xff0c;加上一台服务器处理能里的有限性&#xff0c;在如今高并发、业务复杂的场景下很难达到咱们的要求。但是若将很多台这样的服务器通过某种方式组成一个整体&#xff0c;并且将所有的请求平均的分配…

Kafka的命令行操作

一、topic命令 下面Windows命令需要把cmd路径切换到bin/windows下。 而Linux命令只需要在控制台切换到bin目录下即可。 下面都以Windows下的操作为例&#xff0c;在Linux下也是一样的。 1.1 查看主题命令的参数 kafka-topics.bat # Windows kafka-topics.sh # Linux输…