区间信息维护与查询【分块】 - 原理 分块详解

news2024/11/15 13:39:29

区间信息维护与查询【分块】 - 原理 分块详解

树状数组和线段树虽然非常方便,但维护的信息必须满足信息合并特性(如区间可加、可减),若不满足此特性,则不可以使用树状数组和线段树。分块算法可以维护一些线段树维护不了的内容,它其实就是优化过后的暴力算法。

分块可以解决几乎所有区间更新和区间查询问题,但效率相对于线段树等数据结构要差一些。

分块算法是将所有数据都分为若干块,维护块内信息,使得块内查询为O (1)时间,而总询问可被看作若干块询问的总和。

分块算法将长度为n 的序列分成若干块,每一块都有k 个元素,最后一块可能少于k 个元素。

为了使时间复杂度均摊,通常将块的大小设为k = √n ,用pos[i ]表示第i 个位置所属的块,对每个块都进行信息维护。分块可以解决以下问题。

  • 单点更新:一般先将对应块的懒标记下传,再暴力更新块的状态,时间复杂度为O (√n)。
  • 区间更新:若区间更新横跨若干块,则只需对完全覆盖的块打上懒标记,最多需要修改两端的两个块,对两端剩余的部分暴力更新块的状态。每次更新都最多遍历 √n 个块,遍历每个块的时间复杂度都是O(1),两端的两个块暴力更新 √n 次,总的时间复杂度是O (√n)。
  • 区间查询:和区间更新类似,对中间跨过的整个块直接利用块存储的信息统计答案,对两端剩余的部分可以暴力扫描统计。时间复杂度和区间修改一样,也是O (√n)。

将整个段分成多个块后进行修改或查询时,对完全覆盖的块直接进行修改,像线段树一样标记或累加;对两端剩余的部分进行暴力修改。

分块算法遵循**“大段维护、局部朴素”**的原则。

【1】预处理

① 将序列分块,然后将每个块都标记左右端点L[i ]和R[i ],对最后一块需要特别处理。n =10,t = √n =3,每3个元素为一块,一共分为4块,最后一块只有一个元素。

在这里插入图片描述

算法代码:

t = sqrt(n * 1.0); //float sqrt (float) , double sqrt (double) , double long sqrt(double long)

int num = n / t;
if(n % t) num ++;

for(int i = 1 ; i <= num ; i++){
	L[i] = (i - 1) * t + 1; // 每一块的左右端点
	R[i] = i * t;
}

R[num] = n;

② 用pos[]标记每个元素所属的块,用sum[]累加每一块的和值。

在这里插入图片描述

算法代码:

for(int i = 1; i <= num ; i ++){
	
	for(int j = L[i] ; j <= R[i] ; j++){
		
		pos[j] = i; //表示属于哪个块
		sum[i] += a[j]; //计算每块的和值
	}
}

【2】 区间更新

区间更新,例如将[l , r ]区间的元素都加上d 。

① 求l 和r 所属的块,p =pos[l ],q =pos[r ]。

② 若属于同一块(p =q ),则对该区间的元素进行暴力修改,同时更新该块的和值。

③ 若不属于同一块,则对中间完全覆盖的块打上懒标记,add[i]+=d ,对首尾两端的元素进行暴力修改。

例如,将[3, 8]区间的元素都加上5,操作过程:①读取3和8所属的块p =pos[3]=1,q =pos[8]=3,不属于同一块,中间的完整块[p +1,q -1]为第2块,为该块打上懒标记add[2]+=5;②对首尾两端的元素(下标3、7、8)进行暴力修改,并修改和值。

在这里插入图片描述

算法代码:

void change(int l , int r, long long d){ // [l ,r] 区间的元素加d
	
	int p = pos[l] , q = pos[r]; //读取所属的块
	if(p == q){ // 在同一块中
		for(int i = 1; i <= r ; i ++){ // 暴力修改
			a[i] += d;
		}
		sum[p] += d * (r - l + 1); //修改和值
	}
	else{
		for(int i = p + 1 ; i <= q - 1; i ++){ // 对中间完全覆盖的块打懒标记
			add[i] += d;	
		}
		for(int i = 1; i <= R[p] ; i++){ // 左端暴力修改
			a[i] += d;
		}
		sum[p] += d * (R[p] - l + 1); //修改和值
		for(int i = L[q] ; i <= r ; i++){ // 右端暴力修改
			a[i] += d;
		}
		sum[q] += d * (r - L[q] + 1); //修改和值
	}
}

【3】区间查询

区间查询,例如查询[l , r ]区间的元素和值。

① 求l 和r 的所属块,p =pos[l ],q =pos[r ]。

② 若属于同一块(p =q ),则对该区间的元素进行暴力累加,然后加上懒标记上的值。

③ 若不属于同一块,则对中间完全覆盖的块累加sum[]值和懒标记上的值,然后对首尾两端暴力累加元素值及懒标记值。

例如,查询[2, 7]区间的元素和值,操作过程:①读p=pos[2]=1,q =pos[7]=3,不属于同一块,则中间的完整块[p +1, q-1]为第2块,ans+=sum[2]+add[2]×(R[2]-L[2]+1)=42+5×3=57;②对首尾两端的元素暴力累加元素值及懒标记值。此时懒标记add[1]=add[3]=0,ans+=5+7+add[1]×(3-2+1)+9+add[3]×(7-7+1)=78。

在这里插入图片描述

算法代码:

ll ask(int l , int r){ // 区间查询
	
	int p = pos[l] , q = pos[r];
	ll ans = 0;
	
	if(p == q){ // 在同一块中
		for(int i = l ; i <= r;  i++){ // 累加
			ans += a[i];
		}
		ans += add[p] * (r - l + 1); // 计算懒标记
	}
	else{
		for(int i = p + 1; i <= q - 1; i ++){ // 累加中间段落
			ans += sum[i] + add[i] * (R[i] - L[i] + 1);
		}
		for(int i = l ; i <= R[p] ; i ++){ // 左端暴力累加
			ans += a[i];
		}
		ans += add[p] * (R[p] - l + 1);
		for(int i  = L[q]; i <= r; i ++){ //右端暴力累加
			ans += a[i];
		}
		ans += add[q] * (r - L[q] + 1);
	}
	return ans;
}

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

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

相关文章

简单入门编写html登录界面

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>你好呀&#xff0c;登录吧</title><style&…

MySQL锁,锁的到底是什么

作者&#xff1a;蝉沐风 博客站点&#xff1a;https://www.chanmufeng.com 公众号&#xff1a;蝉沐风的码场 本文目录1. 资源的竞争方式2. 读—写/写—读下的问题2.1. 幻读2.2. 不可重复读2.3. 脏读2.4. 锁与MVCC的关系2.5. 锁与事务的关系3. 写—写情况4. 锁的粒度5. 锁的基本…

[附源码]计算机毕业设计JAVA校园失物招领管理系统

[附源码]计算机毕业设计JAVA校园失物招领管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

[附源码]计算机毕业设计JAVA新闻发布和评论管理系统

[附源码]计算机毕业设计JAVA新闻发布和评论管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM …

ELK日志平台搭建

平时查看错误日志&#xff0c;都是登录到服务器&#xff0c;然后用命令进行查看&#xff0c;不是很好的定位问题&#xff0c;决定搭建一个ELK的日志查看平台。ELK是Elasticsearch、Logstash、Kibana三个的简称。Elasticsearch是一个分布式的实时搜索引擎&#xff0c;Logstash是…

室内定位:5G定位开启高精度定位新纪元

“5G定位”作为一个新的方向将会对于解决室外到室内的“最后一公里”高精度定位问题发挥更强的赋能和带动作用。 室内定位作为室外定位的技术延伸&#xff0c;弥补了传统定位技术的不足&#xff0c;而5G定位正推动信息社会数字化步入快车道的大趋势&#xff0c;赋能千行百业。 …

DNS查询流程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a; 才疏学浅的木子 &#x1f647;‍♂️ 本人也在学习阶段如若发现问题&#xff0c;请告知非常感谢 &#x1f647;‍♂️ &#x1f4d2; 本文来自专栏&#xff1a; 计算机网络 ❤️ 支持我&#xff1a;&#x1f44d;点赞 &#…

精选20个爆火的Python实战项目(含源码),直接拿走不谢

今天给大家介绍20个非常实用的Python项目&#xff0c;帮助大家更好的学习Python。 ① 猜字游戏 在这个游戏中&#xff0c;你必须一个字母一个字母的猜出秘密单词。 如果你猜错了一个字母&#xff0c;你将丢掉一条命。 正如游戏名那样&#xff0c;你需要仔细选择字母&#x…

Vue笔记_03组件_mavonEditor(基于vue)

目录下载mavonEditor导入并注册mavonEditor组件[1] 全局注册[2]局部注册使用mavonEditor属性修改举例说明1-不展示预览分屏工具栏修改举例说明-根据配置显示工具栏编辑器插槽举例说明-自定义工具栏按钮函数监听下载mavonEditor 使用命令 npm install mavon-editor --s 进行下载…

[附源码]Python计算机毕业设计SSM抗包虫病药物查询与推荐系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]计算机毕业设计预约挂号appSpringboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Flink】flink 状态恢复 because the operator is not available in the new program

1.概述 感谢您抽出 一个flink环境做状态恢复报错:because the operator is not available in the new program。详细错误如下 2.源码分析 2.1 restoreSavepoint restoreSavepoint 是从给定的检查点进行恢复。主要做了如下步骤 检测恢复路径是否存在从外部存储获取 Checkpoi…

【Linux】常用命令

文章目录Linux 常用命令目录结构命令结构目录操作文件操作用户操作通配符Linux 常用命令 目录结构 Windows 以存储介质为主&#xff0c;以盘符&#xff08;C盘D盘&#xff09;分区实现文件管理。Linux 以树形目录为主构建系统&#xff0c;大部分目录结构已规定。Linux中一切皆…

将本地项目添加到github中的其他办法

目录 1.在github上创建一个新仓库 2.git clone 3.将本地的文件夹里面的所有内容拷贝到新克隆下来的文件夹中 4.打开克隆下来的文件 5.git add . 6.git commit -am “注释” 7.git push -u origin master 1.在github上创建一个新仓库 2.git clone 本地克隆刚才创建的项目 3.…

C++数据结构X篇_04_单向链表框架搭建、实现和测试(链表的定义,常用操作的实现等)

接上篇C数据结构X篇_03_线性表的顺序存储和动态数组案例&#xff08;基本概念&#xff1b;操作要点&#xff1b;顺序存储算法&#xff1b;动态数组案例实现&#xff09;&#xff0c;本篇将会开始介绍线性表的链式存储。 参考博文&#xff1a;最详细的C单向链表实现&#xff0c;…

细胞衰老β-半乳糖苷酶染色试剂盒丨艾美捷解决方案

细胞衰老&#xff08;Cell senescence&#xff09;是细胞控制其生长潜能的保障机制&#xff0c;一般含义是复制衰老&#xff08;Replicative senescence&#xff0c;RS&#xff09;&#xff0c;指正常细胞经过有限次数的分裂后&#xff0c;停止分裂&#xff0c;此时细胞虽然是存…

DSP篇--C6678功能调试系列之EMIF、GPIO调试

目录 1、EMIF调试 2、GPIO调试 前言不用多说&#xff0c;详见DSP篇--C6678功能调试系列之DDR3调试_nanke_yh的博客-CSDN博客 1、EMIF调试 EMIF主要是提供挂载的NOR FLASH/NAND FLASH/**RAM上的时序。 EMIF16 can operate in the following modes: • WE Strobe Mode • Sele…

【元胞自动机】元胞自动机求解城市小区开放对周边道路通行影响研究【含Matlab源码 233期】

⛄一、元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 何顿 康威设计了一个电脑游戏 “生命游戏” 后, 元胞自动机才吸引了科学家们的注意. 1983 年…

安全-加密与证书

对称加密 在对称加密中&#xff0c;加密和解密使用的是同一个密钥&#xff0c;即&#xff1a;使用相同的密钥对密文进行加密和解密 比如&#xff1a;A和B&#xff0c;A和B保存同一个密钥&#xff0c;A使用这个密钥对明文进行加密&#xff0c;发送给B&#xff0c;B再使用这个密…

【火灾检测】森林火灾检测系统(带面板)【含GUI Matlab源码 1921期】

⛄一、火灾检测简介 1 引言 目前森林火灾是破坏森林的最主要的灾害之一, 影响很大。森林是各种珍禽异兽的家园, 森林遭受火灾后, 会破坏野生动物赖以生存的环境。严重的森林火灾不仅能引起水土流失, 还会引起山洪爆发、泥石流等自然灾害。因此, 对森林火灾尽早识别并预警, 就能…