前缀和(一维前缀和+二维前缀和)

news2025/4/16 18:47:23

前缀和

定义:

前缀和是指某序列的前n项和,可以把它理解为数学上的数列的前n项和,而差分可以看成前缀和的逆运算。合理的使用前缀和与差分,可以将某些复杂的问题简单化。

用途:

前缀和一般用于统计一个区间的和,为的就是可以将区间和问题的时间复杂度降低,从而节约时间

样例:

假如说我们有一个数组,数组里面有n个元素,给你m个访问,每次给你一个L和R,问你L和R这个区间内的元素的和为多少

我们首先想到的暴力解法应该是每次调用一次for循环,去遍历区间的元素,然后求和,但是这样的时间复杂度在最坏的情况下会达到O(n*m)的时间复杂度,对于大数据来说,这种肯定是要超时的,因此我们可以用到我们的前缀和

首先,我们可以用一个前缀和数组统计出现的和,pre[ i ]放的就是在 i 之前的所有数的和,每次询问,只需要输出pre[ R ] - pre[ L - 1 ]即可,时间复杂度为O(n+m),这样就大大减小的时间复杂度

因此我们可以看到前缀和在多次求解区间和问题上的优势。

一维前缀和

在一维空间内的统计十分简单,只需要设计一个一维pre数组即可

一维前缀和预处理公式

pre[i]=pre[i-1]+a[i];

区间求解公式(从L到R的区间)

pre[R]-pre[L-1]

来看例题

P8218 【深进1.例1】求区间和

题解:很标准的前缀和问题,每次询问的都是一个区间的和,那么我们直接用一维前缀和即可

#include<bits/stdc++.h>
using namespace std;
int n;
int a[100005];
int m;
int pre[100005];
int l,r;

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		pre[i]=pre[i-1]+a[i];
	}
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>l>>r;
		cout<<pre[r]-pre[l-1]<<"\n";
	}
	return 0;
} 

二维前缀和

二维前缀和的计算是基于容斥原理的,我们需要通过对矩阵面积的划分计算来的出二维前缀和的预处理公式和求和公式

预处理公式:

我们通过这个图来了解,二维前缀和的预处理公式,首先我们将元素变成矩阵的一个一个的小方块,我们看如何去求第i行第j列之前的面积,首先我们的矩阵面积可以S(i-1,j)+S(i,j-1)的面积之和,但是多了一部分重叠部分S(i-1,j-1),并且加上额外的有下角元素a(i,j),因此我们的预处理公式就可以得出:

pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];

二维前缀和求和公式:

 也是将计算变为矩阵面积来看,假如说我们想算从(a,b)到(i,j)的前缀和,我们首先可以用整个的大面积( S(i,j) )的面积减去S(a-1,j)和S(i,b-1),但是通过容斥原理发现我们多减一部分,那就是

S(a-1,b-1),因此我们就可以得出二维前缀和求和公式:

pre[i][j]-pre[a-1][j]-pre[i][b-1]+pre[a-1][b-1]

 我们来看一道例题:最大加权矩阵

这道题,一眼就能看出来是二维前缀和,但是由于数据比较小,所以可以暴力枚举其范围,总共四重循环,计算其中前缀和的最大矩阵和,最后输出即可

#include<bits/stdc++.h>
using namespace std;
 
int n;
int a[125][125];
int pre[125][125];

signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
			pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
		}
	}
	int ans=-0x3f3f3f3f;
	for(int x1=1;x1<=n;x1++)
	{
		for(int y1=1;y1<=n;y1++)
		{
			for(int x2=x1;x2<=n;x2++)
			{
				for(int y2=y1;y2<=n;y2++)
				{
					ans=max(ans,pre[x2][y2]-pre[x1-1][y2]-pre[x2][y1-1]+pre[x1-1][y1-1]);
				}
			}
		}
	}
	cout<<ans;
	return 0;
}

P2004 领地选择

题解,就是一个二维前缀和模版,很简单,直接写就OK了,只需要记录其中的左上角坐标就OK

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,c;
int a[1005][1005];
int pre[1005][1005];
int ans=-0x3f3f3f3f3f3f3f3f; 
int x,y;

signed main()
{
	cin>>n>>m>>c;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
		}
	}
	for(int i=c;i<=n;i++)
	{
		for(int j=c;j<=m;j++)
		{
			if(ans<pre[i][j]-pre[i-c][j]-pre[i][j-c]+pre[i-c][j-c])
			{
				ans=pre[i][j]-pre[i-c][j]-pre[i][j-c]+pre[i-c][j-c];
				x=i;
				y=j;
			}
		}
	}
	cout<<x-c+1<<" "<<y-c+1;
	return 0;
}

 

 

前缀和的应用(包括二分思想,这里默认各位看官老爷都会)

P1314 [NOIP2011 提高组] 聪明的质监员

 题意:就是说给你n个矿石,然后,这n个矿石都有自己的重量w,以及其价值v,我们有一种判断机制,就是说给你m个区间范围,每次给你一个左边界L和右边界R,我们的计算机理是,这个区间内的大于规定筛选重量W的数量,乘以大于筛选重量的价值,然后将总的算出来的y累加到一起,看看和规定的标准值S最小差多少,输出最小的参数W

思路,我们发现这题数据超大,必然会有优化方法,我们通过上面·的题意可以发现,我们的参数设置的越大,能过筛选的石头越少,得到的y值越小,设置的越小,能筛选过的石头越多,得到的y值越大,因此我们可以用二分(二分的范围就是给的数据的石头的最小值到最大值,但是我们还要扩增范围,最小值减一,最大值加二)然后我们每次二分的就是参数W,然后在计算过程中要用到前缀和优化,我们要去记录出现的大于参数的矿石数目以及总价值,然后我们去计算总的Y值,Y值大于标准值S就说明,我们的参数设置的小了,要增大左边界,要是小于标准值,就说明,我们的参数设置的太大了,要缩小右边界

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,s;
int w[200005];
int v[200005]; 
int l[200005],r[200005];
int maxn=0;
int minn=0x3f3f3f3f3f3f3f3f;
int sumn[200005];
int sumv[200005];
int ans=0;//统计本次筛选的总价值
int mn=0x3f3f3f3f3f3f3f3f;//统计最小差值 
bool check(int mid)
{
	memset(sumn,0,sizeof(sumn));
	memset(sumv,0,sizeof(sumv));
	int ans=0;//统计总的价值也就是y[i] 
	for(int i=1;i<=n;i++)
	{
		if(w[i]>=mid)
		{
			sumn[i]=sumn[i-1]+1;//统计能过筛查的数量
			sumv[i]=sumv[i-1]+v[i];//统计能过筛查的价值 
		}
		else
		{
			sumn[i]=sumn[i-1];
			sumv[i]=sumv[i-1];
		}
	}
	
	for(int i=1;i<=m;i++)
	{
		ans+=(sumn[r[i]]-sumn[l[i]-1])*(sumv[r[i]]-sumv[l[i]-1]);
	}
	mn=min(mn,llabs(ans-s));
	if(ans>s)
	return true;
	return false;
}
signed main()
{
	cin>>n>>m>>s;
	for(int i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
		maxn=max(maxn,w[i]);//二分的上下边界 
		minn=min(minn,w[i]);
	}
	int left,right,mid;
	for(int i=1;i<=m;i++)
	{
		cin>>l[i]>>r[i];
	}
	left=minn-1,right=maxn+2;
	while(left<=right)
	{
		mid=(left+right)/2;
		if(check(mid))
		{
			left=mid+1;
		}
		else
		{
			right=mid-1;
		}
	}
	cout<<mn;
	return 0;
}

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

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

相关文章

GoldWave 6.80最新版软件安装包下载+详细安装步骤

​GoldWave是一款易上手的专业级数字音频编辑软件&#xff0c;从最简单的录制和编辑到最复杂的音频处理&#xff0c;恢复&#xff0c;增强和转换&#xff0c;它可以完成所有工作&#xff0c;包括WAV、OGG、VOC、 IFF、AIFF、 AIFC、AU、SND、MP3、 MAT、 DWD、 SMP、 VOX、SDS、…

【Intel CVPR 2024】通过图像扩散模型生成高质量360度场景,只需要一个语言模型

在当前人工智能取得突破性进展的时代&#xff0c;从单一输入图像生成全景场景仍是一项关键挑战。大多数现有方法都使用基于扩散的迭代或同步多视角内绘。然而&#xff0c;由于缺乏全局场景布局先验&#xff0c;导致输出结果存在重复对象&#xff08;如卧室中的多张床&#xff0…

【Go】用 Go 原生以及 Gorm 读取 SQLCipher 加密数据库

本文档主要描述通过 https://github.com/mutecomm/go-sqlcipher 生成和读取 SQLCipher 加密数据库以及其中踩的一些坑 用 go 去生成读取 SQLCipher 数据库用 gorm 去读取 SQLCipher 数据库在生成后分别用 DBeaver、db browser 和 sqlcipher 读取 SQLCipher 数据库&#xff0c;…

GIS开发到底能应用在哪些行业 ?

GIS应用的领域到底有多广&#xff1f;恐怕很多GIS从业者都想不到。 尤其是近些年&#xff0c;互联网GIS的普及与发展&#xff0c;GIS技术的应用领域越来越多&#xff0c;涉及的范围也越来越广。很多我们以为跟GIS不相关的行业&#xff0c;都在悄悄用GIS技术。 从大类上分析&a…

EFuse概念解析

EFuse概念解析 EFUSE Key Parameter iNOM 代表的是&#xff0c;Efuse运行时候的电流 tNOM 代表的是&#xff0c;Efuse电流与时间的曲线 INOM通过VOC_Thrs设置 VOC_THRS VOC_THRS/Rsense Vsense采样小于VOC_THRS时候不动作 Vsense采样大于VOC_THRS时候根据Efuse_I2T曲线来…

SpringBoot之请求映射原理

前言 我们发出的请求&#xff0c;SpringMVC是如何精准定位到那个Controller以及具体方法&#xff1f;其实这都是 HandlerMapping 发挥的作用&#xff0c;这篇博文我们以 RequestMappingHandlerMapping 为例并结合源码一步步进行分析。 定义HandlerMapping 默认 HandlerMappi…

数据结构的队列,链表,栈的基础操作

1&#xff1a;队列 #include <stdio.h>#include <stdlib.h>#include "./02队列.h"/** function: 创建一个空的队列* param [ in] * param [out] * return */Sequeue* xinduilie(){Sequeue* sq (Sequeue*)malloc(sizeof(Sequeue)); if(N…

Linux基础IO【II】真的很详细

目录 一.文件描述符 1.重新理解文件 1.推论 2.证明 2.理解文件描述符 1.文件描述符的分配规则 3.如何理解文件操作的本质&#xff1f; 4.输入重定向和输出重定向 1.原理 2.代码实现重定向 3.dup函数 ​编辑 4.命令行中实现重定向 二.关于缓冲区 1.现象 …

Ubuntu系统中网易云音乐编译安装

项目地址&#xff1a; netease-cloud-music-gtk: Linux 平台下基于 Rust GTK 开发的网易云音乐播放器 目录 1.README.md中按照步骤来 2.安装git 3.报错 sudo apt install cmake sudo apt-get install libdbus-1-dev sudo apt install dnf sudo dnf install gettext 继…

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法 下滑查看解决方法 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高…

云原生Kubernetes系列项目实战-k8s集群+高可用负载均衡层+防火墙

一、Kubernetes 区域可采用 Kubeadm 方式进行安装&#xff1a; 名称主机部署服务master192.168.91.10docker、kubeadm、kubelet、kubectl、flannelnode01192.168.91.11docker、kubeadm、kubelet、kubectl、flannelnode02192.168.91.20docker、kubeadm、kubelet、kubectl、flan…

【Numpy】一文向您详细介绍 np.trunc()

【Numpy】一文向您详细介绍 np.trunc() 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&#xff0c;…

诊所管理系统免费软件哪个好一点?

不少诊所管理者&#xff0c;想要寻找一款适合自己诊所的免费诊所管理系统。市场上有多个选择&#xff0c;那么&#xff0c;哪个会好一点呢?在选择适合自己诊所的免费诊所管理系统时&#xff0c;考虑系统的易用性、功能全面性、技术支持以及未来可扩展性是非常重要的。下面&…

算法分析与设计期末考试复习GDPU

重点内容&#xff1a; 绪论&#xff1a; 简单的递推方程求解 1.19(1)(2) 、 教材例题 多个函数按照阶的大小排序 1.18 分治法&#xff1a; 分治法解决芯片测试问题 计算a^n的复杂度为logn的算法&#xff08;快速幂&#xff09; 分治法解决平面最近点对问…

值得关注的BTC二层 BitlayerLabs,以及好用的bitget钱包

值得关注的比特币二层 BitlayerLabs Bitlayer BitlayerLabs 是基于 BitVM 的与比特币安全等效的 Layer2。创新的BitRC-20资产框架为生态系统提供了丰富的资产类别。 为什么推荐bitlayer&#xff1f; Framework Ventures 和 ABCDE Capital 领投&#xff0c;OKX Ventures 等参…

微软开发基于深度学习的地球大气基础模型-Aurora

微软研究院的研究人员开发了大气基础模型“Aurora”&#xff0c;https://arxiv.org/abs/2405.13063v1 利用超过一百万小时的多样化天气和气候数据进行训练&#xff0c;能够预测各种大气条件&#xff0c;包括数据有限、变量异构和极端事件&#xff0c;并在全球空气污染和高分辨…

什么是CPT❓CPT中卖方责任是什么?

CPT :CPT 运费付至 &#xff08;……指定的目的地&#xff09; 运费付至&#xff08;……指定的地点&#xff09;”是指卖方向其指定的承运人交货&#xff0c;但卖方还必须支付将货物运至目的地的运费。即买方承担交货之后一切风险和其他费用。 “承运人”是指任何人&#xff…

LabVIEW开发CAN通讯协议

在LabVIEW中开发CAN&#xff08;Controller Area Network&#xff09;通讯协议时&#xff0c;需要全面考虑硬件选择、驱动安装、通信配置、错误处理、数据解析和实时性等多个方面。本文详细介绍了在LabVIEW中实现CAN通讯时的关键点和最佳实践&#xff0c;确保系统的稳定性、可靠…

VScode对比代码功能

CtrlShiftP选择第一行Compare&#xff0c;当前文件就和选中文件对比改动了。

梯度下降法、牛顿法、条件熵

梯度下降法、牛顿法&#xff08;可见南瓜书&#xff09; 梯度下降法 深度学习&#xff1a;梯度下降法数学表示式的详细推导 牛顿法 条件熵 在李航老师的书中&#xff0c;第六章最大熵模型这里有个条件熵的定义&#xff1a; 推导如下&#xff1a; 其他一些事实&#xff1a;…