算法基础,一维,二维前缀和差分详解

news2024/11/18 11:30:25

目录

1.前缀和

1.一维前缀和

 例题:【模板】前缀和

2.二维前缀和

例题:【模板】二维前缀和

2.差分

1.一维差分 

1.性质:d[i]的前缀和等于a[i]

2.性质:后缀区间修改

例题:【模板】差分

2.二维差分

例题:【模板】二维差分

例题:鼠鼠我鸭


1.前缀和

1.一维前缀和

前缀我们用prefix来表示

在最开始,我们有一个名为a和一个名为prefix的数组

那么prefix[2]的值就为a[1]+a[2]

prefix[3]的值就为a[1]+a[2]+a[3]

那么如何达成这一目的呢,我们用一下这段代码

for(int i = 1; i <= n; i++)
	cin >> a[i];
for(int i = 1; i <= n; i++)
    prefix[i] = prefix[i - 1] + a[i];

 

例题:【模板】前缀和

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;

ll a[N];
ll prefix[N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t,n,q;
	cin >> t;
	while(t--)
	{
		cin >> n >> q;
		for(int i = 1; i <= n; i++)
			cin >> a[i];
		for(int i = 1; i <= n; i++)
			prefix[i] = prefix[i - 1] + a[i];
			
		while(q--)
		{
			int l,r;
			cin >> l >> r;
			cout << prefix[r] - prefix[l - 1] << '\n';
		}
	}
	return 0;
}

2.二维前缀和

prefix[i][j]表示的是从a[1][1]到a[i][j]之间所有数的和

举例:

a数组123
1
2
3

 

p3,3 = p2,3 + p3,2 - p2,2 + a3,3

由此可推出

pi,j = pi-1,j + pi,j-1 - pi - 1,j - 1 + ai,j

例题:【模板】二维前缀和

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e3 + 10;

ll a[N][N],p[N][N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	
	int n,m,q;
	cin >> n >> m >> q;
	
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			cin >> a[i][j];
	
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			p[i][j] = p[i - 1][j] + p[i][j - 1] - p[i - 1][j - 1] + a[i][j];
	
	while(q--)
	{
		int x1,y1,x2,y2;
		cin >> x1 >> y1 >> x2 >> y2;
		cout << p[x2][y2] - p[x1 - 1][y2] - p[x2][y1 - 1] + p[x1 - 1][y1 - 1] << '\n';
	}
	
	return 0;
}

 

2.差分

1.一维差分 

差分数组,命名为d

则d[i] = a[i] - a[i-1](i >= 2)

d[1] = a[1]

1.性质:d[i]的前缀和等于a[i]

举例:

a[3] = d[1] + d[2] + d[3]

可以通过前缀还原为a[i]

2.性质:后缀区间修改

由性质1可知,当我们修改一个d的值时,从它下标开始往后的a数组都会相当的改变那么多的值

举例:

我们让d[3]加1,那么a[3],a[4],a[5]......都会加1。

如果我们再让d[6]减1,就可以使得只有a[3]到a[5]加了1这样的操作。

这样的后缀区间修改,是一个静态的,只能先修改再询问。

例题:【模板】差分

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;

ll a[N];
ll prefix[N];
ll diff[N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,p,q;
	cin >> n >> p >> q;
	
	for(int i = 1; i <= n; i++)
		cin >> a[i];
	for(int i = 1; i <= n; i++)
		diff[i] = a[i] - a[i - 1];
		
	while(p--)
	{
		int l,r,x;
		cin >> l >> r >> x;
		diff[l] += x;
		diff[r + 1] -= x;
	}
	
	for(int i = 1; i <= n; i++)
		a[i] = diff[i] + a[i - 1];
	for(int i = 1; i <= n; i++)
		prefix[i] = prefix[i - 1] + a[i];
		
	while(q--)
	{
		int l,r;
		cin >> l >> r;
		cout << prefix[r] - prefix[l - 1] << '\n';
	}
	
	return 0;
}

2.二维差分

二维差分的规则为:

性质与一维差分相同

例题:【模板】二维差分

 

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e3 + 10;

ll a[N][N],d[N][N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	
	int n,m,q;
	cin >> n >> m >> q;
	
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			cin >> a[i][j];
	
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
		{
			d[i][j] += a[i][j];
			d[i+1][j+1] += a[i][j];
			d[i+1][j] -= a[i][j];
			d[i][j+1] -= a[i][j];
		}
			
	while(q--)
	{
		int x1,y1,x2,y2,c;
		cin >> x1 >> y1 >> x2 >> y2 >> c;
		d[x1][y1] += c;
		d[x2 + 1][y1] -= c;
		d[x1][y2+1] -= c;
		d[x2+1][y2+1] += c;
	}
	
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{
			a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + d[i][j];
			cout << a[i][j] << " ";
		}
		cout << '\n';
	}
	
	return 0;
}

例题:鼠鼠我鸭

 

每次释放魔法,会改变最终的结果

假设这个魔法从第一个动物开始使用直到最后一个动物

我们用prefix[i]来表示从第一个动物开始直到第i个动物释放了魔法后算出来的总重量与未释放魔法时的总重量的偏移量

我们找到最小的偏移量的那个坐标和值,并且继续往后移动找到最大的那个偏移量

用最大减去最小,再加上未释放魔法的重量即为答案

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;

ll a[N],w[N],prefix[N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);	
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		cin >> n;
		for(int i = 1; i <= n; i++)
		{
			cin >> a[i];
		}
		for(int i = 1; i <= n; i++)
		{
			cin >> w[i];
		}
		
		//不释放魔法时的答案
		ll ess = 0;
		for(int i = 1; i <= n; i++)
		{
			if(a[i] == 1)
				ess += w[i];
		}
		
		for(int i = 1; i <= n; i++)
		{
			prefix[i] = prefix[i - 1] + w[i] * (a[i] == 1 ? -1 : 1);
			//释放魔法后原来如果是1,答案会减少
		}
		
		ll fix = 0,mi = 0;
		for(int i = 1; i <= n; i++)
		{
			fix = max(fix,prefix[i] - mi);
			mi = min(mi,prefix[i]);
		}
		
		cout << fix + ess << '\n';
	}
	return 0;
}

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

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

相关文章

(已解决)spingboot 后端发送QQ邮箱验证码

打开QQ邮箱pop3请求服务&#xff1a;&#xff08;按照QQ邮箱引导操作&#xff09; 导入依赖&#xff08;不是maven项目就自己添加jar包&#xff09;&#xff1a; <!-- 邮件发送--><dependency><groupId>org.springframework.boot</groupId><…

谷粒商城【成神路】-【4】——分类维护

目录 1.删除功能的实现 2.新增功能的实现 3.修改功能的实现 4.拖拽功能 1.删除功能的实现 1.1逻辑删除 逻辑删除&#xff1a;不删除数据库中真实的数据&#xff0c;用指定字段&#xff0c;显示的表示是否删除 1.在application.yml中加入配置 mybatis-plus:global-config:…

C语言:内存函数(memcpy memmove memset memcmp使用)

和黛玉学编程呀------------- 后续更新的节奏就快啦 memcpy使用和模拟实现 使用 void * memcpy ( void * destination, const void * source, size_t num ) 1.函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 2.这个函数在遇到 \0 的时候…

关于node.js奇数版本不稳定 将11.x.x升级至16.x.x不成功的一系列问题(一)

据说vue2用16稳定一些 vue3用18好一点&#xff08;但之前我vue3用的16.18.1也可以&#xff09; 为维护之前的老项目 先搞定node版本切换 下载nvm node版本管理工具 https://github.com/coreybutler/nvm-windows/releases 用这个nvm-setup.zip安装包 安之前最好先将之前的nod…

Hadoop:HDFS学习巩固——基础习题及编程实战

一 HDFS 选择题 1.对HDFS通信协议的理解错误的是&#xff1f; A.客户端与数据节点的交互是通过RPC&#xff08;Remote Procedure Call&#xff09;来实现的 B.HDFS通信协议都是构建在IoT协议基础之上的 C.名称节点和数据节点之间则使用数据节点协议进行交互 D.客户端通过一…

搭建frp

1.frp 是什么&#xff1f; frp 是一款高性能的反向代理应用&#xff0c;专注于内网穿透。它支持多种协议&#xff0c;包括 TCP、UDP、HTTP、HTTPS 等&#xff0c;并且具备 P2P 通信功能。使用 frp&#xff0c;您可以安全、便捷地将内网服务暴露到公网&#xff0c;通过拥有公网…

【Mysql】事务的隔离级别与 MVCC

事务隔离级别 我们知道 MySQL 是一个 C/S 架构的服务&#xff0c;对于同一个服务器来说&#xff0c;可以有多个客户端与之连接&#xff0c;每个客户端与服务器连接上之后&#xff0c;就是一个会话&#xff08; Session &#xff09;。每个客户端都可以在自己的会话中向服务器发…

pytorch创建tensor

目录 1. 从numpy创建2. 从list创建3. 创建未初始化tensor4. 设置默认tensor创建类型5. rand/rand_like, randint6. randn生成正态分布随机数7. full8. arange/range9. linspace/logspace10. Ones/zeros/eye11. randperm 1. 从numpy创建 2. 从list创建 3. 创建未初始化tensor T…

LabVIEW核能设施监测

LabVIEW核能设施监测 在核能领域&#xff0c;确保设施运行的安全性和效率至关重要。LabVIEW通过与硬件的紧密集成&#xff0c;为高温气冷堆燃料装卸计数系统以及脉冲堆辐射剂量监测与数据管理系统提供了解决方案。这些系统不仅提高了监测和管理的精确度&#xff0c;也保证了核…

C++弹球游戏:Jump Ball Game

一、下载压缩包 请查看网站C弹球游戏&#xff1a;Jump Ball Game并且下载&#xff0c;可以看到如下界面&#xff1a; 二、匹配图标 把压缩包解压了&#xff1a; 右键点击Jump Ball Game.lnk&#xff0c;点击“属性”它将会是我们要运行的文件。 点击“更改图标”&#xff0c;选…

构建用于预警大型语言模型辅助生物威胁创建的系统

深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领域的领跑者。点击订阅&#xff0c;与未来同行&#xff01; 订阅&#xff1a;https://rengongzhineng.io/ 。 Op…

【Docker篇】Linux安装Docker、docker安装mysql、redis、rabbitmq

1.Linux安装docker 官方帮助文档&#xff1a;Install Docker Engine on CentOS | Docker Docs 1.1安装命令 # 1. 卸载之前的dockersudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate…

基于Python的招聘网站爬虫及可视化的设计与实现

摘要&#xff1a;现在&#xff0c;随着互联网网络的飞速发展&#xff0c;人们获取信息的最重要来源也由报纸、电视转变为了互联网。互联网的广泛应用使网络的数据量呈指数增长&#xff0c;让人们得到了更新、更完整的海量信息的同时&#xff0c;也使得人们在提取自己最想要的信…

Web3生态系统:构建去中心化的数字社会

随着科技的飞速发展&#xff0c;我们正处在迈向数字未来的道路上&#xff0c;而Web3生态系统则成为这一变革的中心。不仅仅是技术的演进&#xff0c;Web3代表着对传统互联网体系的颠覆&#xff0c;致力于构建一个去中心化的数字社会。本文将深入探讨Web3的核心特征、对金融、社…

澄清TypeScript中的 `satisfies` 操作符

TypeScript 的 satisfies 运算符已经推出一段时间了&#xff0c;但它似乎仍然是一个可以用来澄清的混乱来源。 可以把 satisfies 看作是将类型赋给值的另一种方式。 在我们深入研究之前&#xff0c;让我们回顾一下如何赋值类型。 首先&#xff0c;有一个不起眼的“冒号注解”…

用python实现pdf按页切割,以及将pdf转成图片

我们经常遇到需要切割pdf的时候&#xff0c;但是常规手段很难做到 我们可以利用python脚本来实现 需要安装几个库 tk PyPDF2 PyMuPDF pyinstaller 上图&#xff01; 查看结果 切割pdf转存成图像 那我们来详细说一下使用方法 1.输入PDF位置:这里没什么好说的&#xff0c…

基于SpringBoot开发的校刊投稿系统[附源码]

基于SpringBoot开发的校刊投稿系统[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#x1f…

【Springcloud篇】学习笔记十(十七章):Sentinel实现熔断与限流——Hystrix升级

第十七章_Sentinel实现熔断与限流 1.Sentinel介绍 1.1是什么 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 用来代替Hystrix Sentinel 具有…

[word] word大小写快捷键是什么? #知识分享#学习方法#笔记

word大小写快捷键是什么&#xff1f; word转换大小写的快捷方式是按“ShiftF3”。设置方法如下&#xff1a; 1、在电脑桌面找到需要转换大小写的文档&#xff0c;右键单击打开它。 2、打开文档之后&#xff0c;在文档里面选中需要转换的段落。 3、选中了之后在键盘里面找到“…

Java:你还在想着考虑使用 tess4j 做文字识别吗?给你看看我的一点实践

需求&#xff1a;删除带有图片水印的图片 语言也设置为中文了&#xff0c;最后给我识别的文字是这样的 | AT V ! w{)" . ) ,/ R Ko 87 ’ 我能理解&#xff0c;毕竟图片很大张&#xff0c;不过不用担心&#xff0c;因为这个水印很有规律&#xff0c;就在右下方裁剪出宽 1…